mirror of
https://codeberg.org/icewind/vdf-reader.git
synced 2026-06-03 18:14:07 +02:00
boxed arrays
This commit is contained in:
parent
778696590a
commit
d54e44b51d
7 changed files with 143 additions and 6 deletions
36
src/error.rs
36
src/error.rs
|
|
@ -42,6 +42,42 @@ pub enum VdfError {
|
|||
Other(String),
|
||||
}
|
||||
|
||||
impl VdfError {
|
||||
pub(crate) fn with_source_span<Sp: Into<SourceSpan>, Sr: Into<String>>(
|
||||
self,
|
||||
span: Sp,
|
||||
source: Sr,
|
||||
) -> VdfError {
|
||||
match self {
|
||||
VdfError::UnexpectedToken(e) => UnexpectedTokenError {
|
||||
src: source.into(),
|
||||
err_span: span.into(),
|
||||
..e
|
||||
}
|
||||
.into(),
|
||||
VdfError::NoValidToken(e) => NoValidTokenError {
|
||||
src: source.into(),
|
||||
err_span: span.into(),
|
||||
..e
|
||||
}
|
||||
.into(),
|
||||
VdfError::WrongEntryType(e) => WrongEventTypeError {
|
||||
src: source.into(),
|
||||
err_span: span.into(),
|
||||
..e
|
||||
}
|
||||
.into(),
|
||||
VdfError::SerdeParse(e) => SerdeParseError {
|
||||
src: source.into(),
|
||||
err_span: span.into(),
|
||||
..e
|
||||
}
|
||||
.into(),
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ExpectedTokens<'a>(&'a [Token]);
|
||||
|
||||
impl Display for ExpectedTokens<'_> {
|
||||
|
|
|
|||
67
src/serde.rs
67
src/serde.rs
|
|
@ -293,9 +293,17 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let token = self.peek().expect_token(STRING_ITEMS, self.source())?;
|
||||
let value_str = &self.source()[token.span.clone()];
|
||||
if value_str.starts_with("\"[") && value_str.ends_with("]\"") {
|
||||
let _ = self.next();
|
||||
let seq = &value_str[2..value_str.len() - 2];
|
||||
let span = token.span.start + 2..token.span.end - 2;
|
||||
visitor.visit_seq(StringArrayWalker::new(self.source(), seq, span))
|
||||
} else {
|
||||
let key = self.last_key.clone();
|
||||
let value = visitor.visit_seq(SeqWalker::new(&mut self, key))?;
|
||||
Ok(value)
|
||||
visitor.visit_seq(SeqWalker::new(&mut self, key))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
|
||||
|
|
@ -322,16 +330,16 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
V: Visitor<'de>,
|
||||
{
|
||||
// as a special case we allow a map without a `{` at the start of the file to create a top level struct
|
||||
let toplevel = match dbg!(self
|
||||
let toplevel = match self
|
||||
.peek()
|
||||
.expect_token(&[Token::GroupStart], self.source()))
|
||||
.expect_token(&[Token::GroupStart], self.source())
|
||||
{
|
||||
Ok(_) => {
|
||||
let _ = self.next();
|
||||
false
|
||||
}
|
||||
Err(VdfError::UnexpectedToken(e)) => {
|
||||
if dbg!(self.tokenizer.count) > 1 {
|
||||
if self.tokenizer.count > 1 {
|
||||
return Err(e.into());
|
||||
}
|
||||
true
|
||||
|
|
@ -526,6 +534,55 @@ impl<'de, 'a> SeqAccess<'de> for SeqWalker<'de, 'a> {
|
|||
}
|
||||
}
|
||||
|
||||
struct StringArrayWalker<'source> {
|
||||
source: &'source str,
|
||||
remaining: &'source str,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl<'source> StringArrayWalker<'source> {
|
||||
fn new(source: &'source str, array: &'source str, span: Span) -> Self {
|
||||
StringArrayWalker {
|
||||
source,
|
||||
remaining: array,
|
||||
span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'source> SeqAccess<'de> for StringArrayWalker<'source>
|
||||
where
|
||||
'source: 'de,
|
||||
{
|
||||
type Error = VdfError;
|
||||
|
||||
fn next_element_seed<T>(
|
||||
&mut self,
|
||||
seed: T,
|
||||
) -> std::result::Result<Option<T::Value>, Self::Error>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
if self.remaining.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let (item, rest) = self
|
||||
.remaining
|
||||
.split_once(" ")
|
||||
.unwrap_or((self.remaining, ""));
|
||||
let item_span = self.span.start..(self.span.start + item.len());
|
||||
self.remaining = rest.trim();
|
||||
self.span = (self.span.end - self.remaining.len())..self.span.end;
|
||||
|
||||
let mut de = Deserializer::from_str(item);
|
||||
let val = seed
|
||||
.deserialize(&mut de)
|
||||
.map_err(|e| e.with_source_span(item_span, self.source))?;
|
||||
Ok(Some(val))
|
||||
}
|
||||
}
|
||||
|
||||
struct Enum<'a, 'de: 'a> {
|
||||
de: &'a mut Deserializer<'de>,
|
||||
}
|
||||
|
|
|
|||
5
tests/data/serde_array_type.vdf
Normal file
5
tests/data/serde_array_type.vdf
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
"Types" {
|
||||
fixed_array "[1 2 3]"
|
||||
flex_array "[1.0 2.2]"
|
||||
tuple "[1 57]"
|
||||
}
|
||||
5
tests/errors/serde_array_type.vdf
Normal file
5
tests/errors/serde_array_type.vdf
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
"Types" {
|
||||
fixed_array "[1 2 3.1]"
|
||||
flex_array "[1.0 2.2]"
|
||||
tuple "[1 57]"
|
||||
}
|
||||
|
|
@ -7,6 +7,11 @@ use vdf_reader::from_str;
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
enum Expected {
|
||||
Types {
|
||||
fixed_array: [u8; 3],
|
||||
flex_array: Vec<f32>,
|
||||
tuple: (bool, u8),
|
||||
},
|
||||
LightmappedGeneric {
|
||||
#[serde(rename = "$baseTexture")]
|
||||
base_texture: String,
|
||||
|
|
@ -152,8 +157,10 @@ struct GameList {
|
|||
#[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")]
|
||||
#[test_case("tests/errors/concrete.vmt")]
|
||||
#[test_case("tests/errors/novalue.vdf")]
|
||||
#[test_case("tests/errors/serde_array_type.vdf")]
|
||||
fn test_serde(path: &str) {
|
||||
let raw = read_to_string(path).unwrap();
|
||||
match from_str::<Expected>(&raw) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: tests/serde.rs
|
||||
expression: result
|
||||
---
|
||||
Types(
|
||||
fixed_array: (1, 2, 3),
|
||||
flex_array: [
|
||||
1.0,
|
||||
2.2,
|
||||
],
|
||||
tuple: (true, 57),
|
||||
)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
source: tests/serde.rs
|
||||
expression: out
|
||||
---
|
||||
vmt_parser::parse_serde
|
||||
|
||||
× Can't parse "3.1" as u8
|
||||
╭─[1:1]
|
||||
1 │ "Types" {
|
||||
2 │ fixed_array "[1 2 3.1]"
|
||||
· ─┬─
|
||||
· ╰── Expected a u8
|
||||
3 │ flex_array "[1.0 2.2]"
|
||||
╰────
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue