mirror of
https://codeberg.org/icewind/vdf-reader.git
synced 2026-06-03 18:14:07 +02:00
serde for Entry/Table/Statement/Value
This commit is contained in:
parent
6a332d051f
commit
d7d26f530a
14 changed files with 367 additions and 72 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -223,6 +223,12 @@ dependencies = [
|
|||
"logos-codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
|
|
@ -607,6 +613,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"insta",
|
||||
"logos",
|
||||
"maplit",
|
||||
"miette",
|
||||
"parse-display",
|
||||
"serde",
|
||||
|
|
|
|||
|
|
@ -16,3 +16,4 @@ test-case = "3.3.1"
|
|||
insta = { version = "1.34.0", features = ["ron"] }
|
||||
miette = { version = "5.10.0", features = ["fancy"] }
|
||||
walkdir = "2.4.0"
|
||||
maplit = "1.0.2"
|
||||
|
|
|
|||
123
src/entry/mod.rs
123
src/entry/mod.rs
|
|
@ -8,12 +8,14 @@ use crate::Item;
|
|||
pub use array::Array;
|
||||
pub use statement::Statement;
|
||||
use std::any::type_name;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Formatter;
|
||||
use std::slice;
|
||||
pub use table::Table;
|
||||
pub use value::Value;
|
||||
|
||||
/// The kinds of entry.
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Entry {
|
||||
/// A table.
|
||||
|
|
@ -22,11 +24,11 @@ pub enum Entry {
|
|||
/// An array (entries with the same key).
|
||||
Array(Array),
|
||||
|
||||
/// A statement (the values starting with #).
|
||||
Statement(Statement),
|
||||
|
||||
/// A value.
|
||||
Value(Value),
|
||||
|
||||
/// A statement (the values starting with #).
|
||||
Statement(Statement),
|
||||
}
|
||||
|
||||
impl From<Item<'_>> for Entry {
|
||||
|
|
@ -175,7 +177,8 @@ macro_rules! from_str {
|
|||
);
|
||||
}
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::de::{Error, MapAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
from_str!(for IpAddr Ipv4Addr Ipv6Addr SocketAddr SocketAddrV4 SocketAddrV6);
|
||||
from_str!(for i8 i16 i32 i64 isize u8 u16 u32 u64 usize f32 f64);
|
||||
|
|
@ -230,3 +233,113 @@ impl<T: ParseItem> ParseItem for Option<T> {
|
|||
T::from_str(item).map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Entry {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct EntryVisitor;
|
||||
|
||||
impl<'v> Visitor<'v> for EntryVisitor {
|
||||
type Value = Entry;
|
||||
|
||||
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
|
||||
write!(formatter, "any string like value or group")
|
||||
}
|
||||
|
||||
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(Entry::Value(v.to_string().into()))
|
||||
}
|
||||
|
||||
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(Entry::Value(v.to_string().into()))
|
||||
}
|
||||
|
||||
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(Entry::Value(v.to_string().into()))
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
if v.starts_with('#') {
|
||||
Ok(Entry::Statement(v.to_string().into()))
|
||||
} else {
|
||||
Ok(Entry::Value(v.to_string().into()))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
if v.starts_with('#') {
|
||||
Ok(Entry::Statement(v.into()))
|
||||
} else {
|
||||
Ok(Entry::Value(v.into()))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
let v = if v { "1" } else { "0" };
|
||||
Ok(Entry::Value(v.to_string().into()))
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: MapAccess<'v>,
|
||||
{
|
||||
let mut res = HashMap::new();
|
||||
|
||||
while let Some(entry) = map.next_entry()? {
|
||||
res.insert(entry.0, entry.1);
|
||||
}
|
||||
|
||||
Ok(Entry::Table(res.into()))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(EntryVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[track_caller]
|
||||
fn unwrap_err<T>(r: Result<T, crate::VdfError>) -> T {
|
||||
r.map_err(miette::Error::from).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serde_entry() {
|
||||
use maplit::hashmap;
|
||||
|
||||
let j = r#"1"#;
|
||||
assert_eq!(Entry::Value("1".into()), unwrap_err(crate::from_str(j)));
|
||||
|
||||
let j = r#""foo bar""#;
|
||||
assert_eq!(
|
||||
Entry::Value("foo bar".into()),
|
||||
unwrap_err(crate::from_str(j))
|
||||
);
|
||||
|
||||
let j = r#"{foo bar}"#;
|
||||
|
||||
assert_eq!(
|
||||
Entry::Table(hashmap! {"foo".into() => Entry::Value("bar".into())}.into()),
|
||||
unwrap_err(crate::from_str(j))
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,17 @@ impl From<Statement> for Entry {
|
|||
Entry::Statement(statement)
|
||||
}
|
||||
}
|
||||
impl From<&'_ str> for Statement {
|
||||
fn from(value: &str) -> Statement {
|
||||
Statement(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Statement {
|
||||
fn from(value: String) -> Statement {
|
||||
Statement(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Statement> for String {
|
||||
fn from(value: Statement) -> Self {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,12 @@ use std::ops::Deref;
|
|||
#[serde(transparent)]
|
||||
pub struct Table(#[serde(serialize_with = "ordered_map")] HashMap<String, Entry>);
|
||||
|
||||
impl From<HashMap<String, Entry>> for Table {
|
||||
fn from(value: HashMap<String, Entry>) -> Self {
|
||||
Table(value)
|
||||
}
|
||||
}
|
||||
|
||||
fn ordered_map<S, K: Ord + Serialize, V: Serialize>(
|
||||
value: &HashMap<K, V>,
|
||||
serializer: S,
|
||||
|
|
@ -90,3 +96,21 @@ impl Deref for Table {
|
|||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[track_caller]
|
||||
fn unwrap_err<T>(r: Result<T, crate::VdfError>) -> T {
|
||||
r.map_err(miette::Error::from).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serde_table() {
|
||||
use maplit::hashmap;
|
||||
|
||||
let j = r#"{foo bar}"#;
|
||||
|
||||
assert_eq!(
|
||||
Table(hashmap! {"foo".into() => Entry::Value("bar".into())}),
|
||||
unwrap_err(crate::from_str(j))
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
use super::Entry;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::de::{Error, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Formatter;
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct Value(String);
|
||||
|
||||
impl From<Cow<'_, str>> for Value {
|
||||
|
|
@ -11,6 +14,17 @@ impl From<Cow<'_, str>> for Value {
|
|||
Value(value.into())
|
||||
}
|
||||
}
|
||||
impl From<&'_ str> for Value {
|
||||
fn from(value: &str) -> Value {
|
||||
Value(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Value {
|
||||
fn from(value: String) -> Value {
|
||||
Value(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Value> for Entry {
|
||||
fn from(value: Value) -> Self {
|
||||
|
|
@ -31,3 +45,79 @@ impl Deref for Value {
|
|||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Value {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct ValueVisitor;
|
||||
|
||||
impl Visitor<'_> for ValueVisitor {
|
||||
type Value = String;
|
||||
|
||||
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
|
||||
write!(formatter, "any string like value")
|
||||
}
|
||||
|
||||
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(v.to_string())
|
||||
}
|
||||
|
||||
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(v.to_string())
|
||||
}
|
||||
|
||||
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(v.to_string())
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(v.into())
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(if v { "1".into() } else { "0".into() })
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(ValueVisitor).map(Value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[track_caller]
|
||||
fn unwrap_err<T>(r: Result<T, crate::VdfError>) -> T {
|
||||
r.map_err(miette::Error::from).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serde_value() {
|
||||
let j = r#"1"#;
|
||||
assert_eq!(Value("1".into()), unwrap_err(crate::from_str(j)));
|
||||
|
||||
let j = r#""foo bar""#;
|
||||
assert_eq!(Value("foo bar".into()), unwrap_err(crate::from_str(j)));
|
||||
}
|
||||
|
|
|
|||
12
src/serde.rs
12
src/serde.rs
|
|
@ -134,9 +134,15 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
}
|
||||
}
|
||||
Token::GroupStart => {
|
||||
self.push_peeked(token);
|
||||
self.deserialize_map(visitor)
|
||||
.ensure_span(span, self.source())
|
||||
let res = visitor.visit_map(TableWalker::new(self, false));
|
||||
let span = span.start..self.last_span.end;
|
||||
res.ensure_span(span.clone(), self.source()).map_err(|e| {
|
||||
if e.span().map(|s| s.offset()) == Some(span.start) {
|
||||
e.with_source_span(span, self.source())
|
||||
} else {
|
||||
e
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||
use std::collections::BTreeMap;
|
||||
use std::fs::read_to_string;
|
||||
use test_case::test_case;
|
||||
use vdf_reader::entry::Table;
|
||||
use vdf_reader::from_str;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
|
@ -188,3 +189,21 @@ fn test_serde(path: &str) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test_case("tests/data/toplevel.vdf")]
|
||||
#[test_case("tests/data/concrete.vmt")]
|
||||
// #[test_case("tests/data/messy.vdf")]
|
||||
// #[test_case("tests/data/DialogConfigOverlay_1280x720.vdf")]
|
||||
// #[test_case("tests/data/serde_array_type.vdf")]
|
||||
fn test_serde_table(path: &str) {
|
||||
let raw = read_to_string(path).unwrap();
|
||||
match from_str::<Table>(&raw) {
|
||||
Ok(result) => insta::assert_ron_snapshot!(format!("table__{}", path), result),
|
||||
Err(e) => {
|
||||
let handler = GraphicalReportHandler::new_themed(GraphicalTheme::unicode_nocolor());
|
||||
let mut out = String::new();
|
||||
handler.render_report(&mut out, &e).unwrap();
|
||||
insta::assert_snapshot!(format!("table__{}", path), out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,29 +9,29 @@ expression: parsed
|
|||
"FriendsDialogSheet": {
|
||||
"FriendsClansPage": {
|
||||
"BuddyList": {
|
||||
"0_collapsed": Value("0"),
|
||||
"1_collapsed": Value("0"),
|
||||
"2_collapsed": Value("0"),
|
||||
"3_collapsed": Value("0"),
|
||||
"0_collapsed": "0",
|
||||
"1_collapsed": "0",
|
||||
"2_collapsed": "0",
|
||||
"3_collapsed": "0",
|
||||
},
|
||||
},
|
||||
"FriendsFriendsPage": {
|
||||
"BuddyList": {
|
||||
"0_collapsed": Value("0"),
|
||||
"1_collapsed": Value("0"),
|
||||
"2_collapsed": Value("0"),
|
||||
"3_collapsed": Value("0"),
|
||||
"4_collapsed": Value("0"),
|
||||
"5_collapsed": Value("0"),
|
||||
"allfriends_collapsed": Value("0"),
|
||||
"0_collapsed": "0",
|
||||
"1_collapsed": "0",
|
||||
"2_collapsed": "0",
|
||||
"3_collapsed": "0",
|
||||
"4_collapsed": "0",
|
||||
"5_collapsed": "0",
|
||||
"allfriends_collapsed": "0",
|
||||
},
|
||||
},
|
||||
},
|
||||
"FriendsState": {},
|
||||
"tall": Value("440"),
|
||||
"wide": Value("252"),
|
||||
"xpos": Value("1028"),
|
||||
"ypos": Value("280"),
|
||||
"tall": "440",
|
||||
"wide": "252",
|
||||
"xpos": "1028",
|
||||
"ypos": "280",
|
||||
},
|
||||
"Servers": {
|
||||
"DialogServerBrowser.res": {
|
||||
|
|
@ -47,10 +47,10 @@ expression: parsed
|
|||
"#ServerBrowser_Players_hidden": "0",
|
||||
"#ServerBrowser_Secure_hidden": "0",
|
||||
"#ServerBrowser_Servers_hidden": "0",
|
||||
"sort_column": Value("#ServerBrowser_Latency"),
|
||||
"sort_column_asc": Value("1"),
|
||||
"sort_column_secondary": Value(""),
|
||||
"sort_column_secondary_asc": Value("1"),
|
||||
"sort_column": "#ServerBrowser_Latency",
|
||||
"sort_column_asc": "1",
|
||||
"sort_column_secondary": "",
|
||||
"sort_column_secondary_asc": "1",
|
||||
},
|
||||
},
|
||||
"FriendsGames": {
|
||||
|
|
@ -64,10 +64,10 @@ expression: parsed
|
|||
"#ServerBrowser_Players_hidden": "0",
|
||||
"#ServerBrowser_Secure_hidden": "0",
|
||||
"#ServerBrowser_Servers_hidden": "0",
|
||||
"sort_column": Value("#ServerBrowser_Latency"),
|
||||
"sort_column_asc": Value("1"),
|
||||
"sort_column_secondary": Value(""),
|
||||
"sort_column_secondary_asc": Value("1"),
|
||||
"sort_column": "#ServerBrowser_Latency",
|
||||
"sort_column_asc": "1",
|
||||
"sort_column_secondary": "",
|
||||
"sort_column_secondary_asc": "1",
|
||||
},
|
||||
},
|
||||
"HistoryGames": {
|
||||
|
|
@ -82,10 +82,10 @@ expression: parsed
|
|||
"#ServerBrowser_Players_hidden": "0",
|
||||
"#ServerBrowser_Secure_hidden": "0",
|
||||
"#ServerBrowser_Servers_hidden": "0",
|
||||
"sort_column": Value("#ServerBrowser_LastPlayed"),
|
||||
"sort_column_asc": Value("1"),
|
||||
"sort_column_secondary": Value("#ServerBrowser_Latency"),
|
||||
"sort_column_secondary_asc": Value("1"),
|
||||
"sort_column": "#ServerBrowser_LastPlayed",
|
||||
"sort_column_asc": "1",
|
||||
"sort_column_secondary": "#ServerBrowser_Latency",
|
||||
"sort_column_secondary_asc": "1",
|
||||
},
|
||||
},
|
||||
"InternetGames": {
|
||||
|
|
@ -99,10 +99,10 @@ expression: parsed
|
|||
"#ServerBrowser_Players_hidden": "0",
|
||||
"#ServerBrowser_Secure_hidden": "0",
|
||||
"#ServerBrowser_Servers_hidden": "0",
|
||||
"sort_column": Value("#ServerBrowser_Latency"),
|
||||
"sort_column_asc": Value("1"),
|
||||
"sort_column_secondary": Value(""),
|
||||
"sort_column_secondary_asc": Value("1"),
|
||||
"sort_column": "#ServerBrowser_Latency",
|
||||
"sort_column_asc": "1",
|
||||
"sort_column_secondary": "",
|
||||
"sort_column_secondary_asc": "1",
|
||||
},
|
||||
},
|
||||
"LanGames": {
|
||||
|
|
@ -116,10 +116,10 @@ expression: parsed
|
|||
"#ServerBrowser_Players_hidden": "0",
|
||||
"#ServerBrowser_Secure_hidden": "0",
|
||||
"#ServerBrowser_Servers_hidden": "0",
|
||||
"sort_column": Value("#ServerBrowser_Latency"),
|
||||
"sort_column_asc": Value("1"),
|
||||
"sort_column_secondary": Value(""),
|
||||
"sort_column_secondary_asc": Value("1"),
|
||||
"sort_column": "#ServerBrowser_Latency",
|
||||
"sort_column_asc": "1",
|
||||
"sort_column_secondary": "",
|
||||
"sort_column_secondary_asc": "1",
|
||||
},
|
||||
},
|
||||
"SpectateGames": {
|
||||
|
|
@ -133,17 +133,17 @@ expression: parsed
|
|||
"#ServerBrowser_Players_hidden": "0",
|
||||
"#ServerBrowser_Secure_hidden": "0",
|
||||
"#ServerBrowser_Servers_hidden": "0",
|
||||
"sort_column": Value("#ServerBrowser_Latency"),
|
||||
"sort_column_asc": Value("1"),
|
||||
"sort_column_secondary": Value(""),
|
||||
"sort_column_secondary_asc": Value("1"),
|
||||
"sort_column": "#ServerBrowser_Latency",
|
||||
"sort_column_asc": "1",
|
||||
"sort_column_secondary": "",
|
||||
"sort_column_secondary_asc": "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
"tall": Value("720"),
|
||||
"wide": Value("1280"),
|
||||
"xpos": Value("0"),
|
||||
"ypos": Value("0"),
|
||||
"tall": "720",
|
||||
"wide": "1280",
|
||||
"xpos": "0",
|
||||
"ypos": "0",
|
||||
},
|
||||
},
|
||||
"Steam": {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ expression: parsed
|
|||
---
|
||||
{
|
||||
"LightmappedGeneric": {
|
||||
"$baseTexture": Value("cp_mountainlab/concrete/concretefloor003"),
|
||||
"$bumpmap": Value("concrete/concretefloor007b_height-ssbump"),
|
||||
"$detail": Value("overlays/detail001"),
|
||||
"$detailblendfactor": Value("1"),
|
||||
"$detailblendmode": Value("0"),
|
||||
"$detailscale": Value("1.9"),
|
||||
"$ssbump": Value("1"),
|
||||
"%keywords": Value("tf"),
|
||||
"$baseTexture": "cp_mountainlab/concrete/concretefloor003",
|
||||
"$bumpmap": "concrete/concretefloor007b_height-ssbump",
|
||||
"$detail": "overlays/detail001",
|
||||
"$detailblendfactor": "1",
|
||||
"$detailblendmode": "0",
|
||||
"$detailscale": "1.9",
|
||||
"$ssbump": "1",
|
||||
"%keywords": "tf",
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ expression: parsed
|
|||
---
|
||||
{
|
||||
"Resource/specificPanel.res": {
|
||||
"$envmaptint": Value(".5"),
|
||||
".5": Value(".5"),
|
||||
"\\\\\"$translucent\"": Value("1"),
|
||||
"$envmaptint": ".5",
|
||||
".5": ".5",
|
||||
"\\\\\"$translucent\"": "1",
|
||||
"array": [
|
||||
Value("1"),
|
||||
Value("2"),
|
||||
Value("3"),
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
],
|
||||
"empty": Value(""),
|
||||
"empty quoted": Value("\"\""),
|
||||
"windows_path": Value("C:\\test\\no newline"),
|
||||
"empty": "",
|
||||
"empty quoted": "\"\"",
|
||||
"windows_path": "C:\\test\\no newline",
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@ source: tests/parse.rs
|
|||
expression: parsed
|
||||
---
|
||||
{
|
||||
"bar": Value("asd"),
|
||||
"foo": Value("1"),
|
||||
"bar": "asd",
|
||||
"foo": "1",
|
||||
}
|
||||
|
|
|
|||
16
tests/snapshots/serde__table__tests__data__concrete.vmt.snap
Normal file
16
tests/snapshots/serde__table__tests__data__concrete.vmt.snap
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
source: tests/serde.rs
|
||||
expression: result
|
||||
---
|
||||
{
|
||||
"LightmappedGeneric": {
|
||||
"$baseTexture": "cp_mountainlab/concrete/concretefloor003",
|
||||
"$bumpmap": "concrete/concretefloor007b_height-ssbump",
|
||||
"$detail": "overlays/detail001",
|
||||
"$detailblendfactor": "1",
|
||||
"$detailblendmode": "0",
|
||||
"$detailscale": "1.9",
|
||||
"$ssbump": "1",
|
||||
"%keywords": "tf",
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
source: tests/serde.rs
|
||||
expression: result
|
||||
---
|
||||
{
|
||||
"bar": "asd",
|
||||
"foo": "1",
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue