mirror of
https://codeberg.org/icewind/vdf-reader.git
synced 2026-06-04 02:24:08 +02:00
fix sequence at end of group, support bare sequences
This commit is contained in:
parent
eeeb47560b
commit
fe7bc149d6
10 changed files with 110 additions and 22 deletions
|
|
@ -122,6 +122,20 @@ impl Entry {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse<'a, T: Deserialize<'a>>(&'a self) -> Result<T, ParseEntryError> {
|
||||
let str = self
|
||||
.as_str()
|
||||
.ok_or_else(|| ParseEntryError::new(type_name::<T>(), self.clone()))?;
|
||||
let mut deserializer = crate::serde::Deserializer::from_str(str);
|
||||
let result = T::deserialize(&mut deserializer)
|
||||
.map_err(|_| ParseEntryError::new(type_name::<T>(), self.clone()))?;
|
||||
if deserializer.next().is_some() {
|
||||
Err(ParseEntryError::new(type_name::<T>(), self.clone()))
|
||||
} else {
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parsable types.
|
||||
|
|
@ -771,6 +785,21 @@ fn test_serde_entry() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_entry() {
|
||||
assert_eq!(1, Entry::Value("1".into()).parse::<usize>().unwrap());
|
||||
assert_eq!(
|
||||
vec!(1, 2, 3),
|
||||
Entry::Value("1 2 3".into()).parse::<Vec<u8>>().unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
(1, 2, 3),
|
||||
Entry::Value("1 2 3".into())
|
||||
.parse::<(u8, u8, u8)>()
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn string_is_array(string: &str) -> bool {
|
||||
(string.starts_with('[') && string.ends_with(']'))
|
||||
|| (string.starts_with('{') && string.ends_with('}'))
|
||||
|
|
|
|||
65
src/serde.rs
65
src/serde.rs
|
|
@ -484,7 +484,7 @@ impl<'source, 'a> TableWalker<'source, 'a> {
|
|||
self.de.source()
|
||||
}
|
||||
|
||||
fn key_token(&mut self) -> Result<Option<SpannedToken>> {
|
||||
fn key_token(&mut self, retain_group_end: bool) -> Result<Option<SpannedToken>> {
|
||||
if self.done {
|
||||
return Ok(None);
|
||||
}
|
||||
|
|
@ -512,6 +512,9 @@ impl<'source, 'a> TableWalker<'source, 'a> {
|
|||
|
||||
if key.token == Token::GroupEnd {
|
||||
self.done = true;
|
||||
if retain_group_end {
|
||||
self.de.push_peeked(key);
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
Ok(Some(key))
|
||||
|
|
@ -525,7 +528,7 @@ impl<'de> MapAccess<'de> for TableWalker<'de, '_> {
|
|||
where
|
||||
K: DeserializeSeed<'de>,
|
||||
{
|
||||
let key = match self.key_token() {
|
||||
let key = match self.key_token(false) {
|
||||
Ok(Some(key)) => key,
|
||||
Ok(None) => {
|
||||
return Ok(None);
|
||||
|
|
@ -585,20 +588,37 @@ impl<'de> SeqAccess<'de> for SeqWalker<'de, '_> {
|
|||
if self.done {
|
||||
return Ok(None);
|
||||
}
|
||||
let value = seed.deserialize(&mut *self.table.de).map(Some)?;
|
||||
|
||||
let key_token = match self.table.key_token() {
|
||||
Ok(Some(key)) => key,
|
||||
Ok(None) => {
|
||||
return Ok(None);
|
||||
}
|
||||
let value = match seed.deserialize(&mut *self.table.de) {
|
||||
Ok(value) => Some(value),
|
||||
Err(VdfError::NoValidToken(_)) => None,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
let key = key_token.string(self.source());
|
||||
if key != self.key {
|
||||
self.table.de.push_peeked(key_token);
|
||||
self.done = true;
|
||||
let value_span = self.table.de.last_span.clone();
|
||||
let newline = match self.table.de.peek_span() {
|
||||
Some(next_span) => {
|
||||
let whitespace = &self.source()[value_span.end..next_span.start];
|
||||
whitespace.contains('\n')
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if newline {
|
||||
let key_token = match self.table.key_token(true) {
|
||||
Ok(Some(key)) => key,
|
||||
Ok(None) => {
|
||||
self.done = true;
|
||||
return Ok(value);
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
let key = key_token.string(self.source());
|
||||
if key != self.key {
|
||||
self.table.de.push_peeked(key_token);
|
||||
self.done = true;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
|
|
@ -866,4 +886,25 @@ mod tests {
|
|||
let j = r#"1.1"#;
|
||||
assert_eq!(E::Float(1.1), unwrap_err(from_str(j)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_in_struct() {
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
struct Test {
|
||||
seq: Vec<u8>,
|
||||
}
|
||||
|
||||
let j = r#"{
|
||||
seq 1
|
||||
seq 2
|
||||
seq 3
|
||||
}"#;
|
||||
let expected = Test { seq: vec![1, 2, 3] };
|
||||
assert_eq!(expected, unwrap_err(from_str(j)));
|
||||
|
||||
let j = r#"{
|
||||
seq 1 2 3
|
||||
}"#;
|
||||
assert_eq!(expected, unwrap_err(from_str(j)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue