mirror of
https://codeberg.org/icewind/vdf-reader.git
synced 2026-06-03 18:14:07 +02:00
better array string handling
This commit is contained in:
parent
31977b9340
commit
d14f22d1bc
6 changed files with 68 additions and 10 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use super::Entry;
|
||||
use crate::entry::Value;
|
||||
use crate::VdfError;
|
||||
use serde::de::{DeserializeSeed, SeqAccess};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -9,6 +10,18 @@ use std::ops::{Deref, DerefMut};
|
|||
#[serde(transparent)]
|
||||
pub struct Array(Vec<Entry>);
|
||||
|
||||
impl Array {
|
||||
pub(crate) fn from_space_separated(str: &str) -> Self {
|
||||
let items = str
|
||||
.split(' ')
|
||||
.filter(|part| !part.is_empty())
|
||||
.map(Value::from)
|
||||
.map(Entry::from)
|
||||
.collect();
|
||||
Array(items)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Entry>> for Array {
|
||||
fn from(value: Vec<Entry>) -> Self {
|
||||
Array(value)
|
||||
|
|
|
|||
|
|
@ -353,6 +353,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_bool(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_bool(visitor),
|
||||
_ => Err(UnknownError::from("bool").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -363,6 +364,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_i8(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_i8(visitor),
|
||||
_ => Err(UnknownError::from("i8").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -373,6 +375,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_i16(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_i16(visitor),
|
||||
_ => Err(UnknownError::from("i16").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -383,6 +386,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_i32(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_i32(visitor),
|
||||
_ => Err(UnknownError::from("i32").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -393,6 +397,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_i64(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_i64(visitor),
|
||||
_ => Err(UnknownError::from("i64").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -403,6 +408,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_u8(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_u8(visitor),
|
||||
_ => Err(UnknownError::from("u8").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -413,6 +419,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_u16(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_u16(visitor),
|
||||
_ => Err(UnknownError::from("u16").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -423,6 +430,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_u32(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_u32(visitor),
|
||||
_ => Err(UnknownError::from("u32").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -433,6 +441,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_u64(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_u64(visitor),
|
||||
_ => Err(UnknownError::from("u64").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -443,6 +452,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_f32(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_f32(visitor),
|
||||
_ => Err(UnknownError::from("f32").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -453,6 +463,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_f64(visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_f64(visitor),
|
||||
_ => Err(UnknownError::from("f64").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -542,6 +553,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
{
|
||||
match self {
|
||||
Entry::Value(val) => val.deserialize_unit_struct(name, visitor),
|
||||
Entry::Statement(val) => Value::from(val).deserialize_unit_struct(name, visitor),
|
||||
_ => Err(UnknownError::from("unit_struct").into()),
|
||||
}
|
||||
}
|
||||
|
|
@ -561,7 +573,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match self {
|
||||
match dbg!(self) {
|
||||
Entry::Array(arr) => visitor.visit_seq(ArraySeq::new(arr)),
|
||||
_ => Err(UnknownError::from("array2").into()),
|
||||
}
|
||||
|
|
@ -571,7 +583,7 @@ impl<'de> Deserializer<'de> for Entry {
|
|||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match self {
|
||||
match dbg!(self) {
|
||||
Entry::Array(arr) => visitor.visit_seq(ArraySeq::new(arr)),
|
||||
_ => Err(UnknownError::from("tuple").into()),
|
||||
}
|
||||
|
|
@ -743,4 +755,23 @@ fn test_serde_entry() {
|
|||
),
|
||||
unwrap_err(crate::from_str(j))
|
||||
);
|
||||
|
||||
let j = r#""{1 2 3}""#;
|
||||
|
||||
assert_eq!(
|
||||
Entry::Array(
|
||||
vec![
|
||||
Value::from("1").into(),
|
||||
Value::from("2").into(),
|
||||
Value::from("3").into()
|
||||
]
|
||||
.into()
|
||||
),
|
||||
unwrap_err(crate::from_str(j))
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn string_is_array(string: &str) -> bool {
|
||||
(string.starts_with('[') && string.ends_with(']'))
|
||||
|| (string.starts_with('{') && string.ends_with('}'))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use super::{Array, Entry};
|
||||
use crate::entry::{Statement, Value};
|
||||
use crate::entry::{string_is_array, Statement, Value};
|
||||
use crate::error::UnknownError;
|
||||
use crate::event::{EntryEvent, GroupStartEvent};
|
||||
use crate::{Event, Item, Reader, Result, VdfError};
|
||||
|
|
@ -70,7 +70,18 @@ impl Table {
|
|||
key: Item::Item { content: key, .. },
|
||||
value,
|
||||
..
|
||||
}) => insert(&mut map, key, Value::from(value.into_content())),
|
||||
}) => {
|
||||
if string_is_array(value.as_str()) {
|
||||
let str = value.as_str();
|
||||
insert(
|
||||
&mut map,
|
||||
key,
|
||||
Array::from_space_separated(&str[1..str.len() - 1]),
|
||||
)
|
||||
} else {
|
||||
insert(&mut map, key, Value::from(value.into_content()))
|
||||
}
|
||||
}
|
||||
|
||||
Event::Entry(EntryEvent {
|
||||
key: Item::Statement { content: key, .. },
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use super::Entry;
|
||||
use crate::entry::{ParseItem, Statement};
|
||||
use crate::entry::{string_is_array, ParseItem, Statement};
|
||||
use crate::error::{ParseStringError, SerdeParseError};
|
||||
use crate::VdfError;
|
||||
use serde::de::{Error, Visitor};
|
||||
|
|
@ -142,7 +142,7 @@ impl<'de> Deserializer<'de> for Value {
|
|||
if let Ok(float) = f64::from_str(&self.0) {
|
||||
return visitor.visit_f64(float);
|
||||
}
|
||||
if self.0.starts_with('[') && self.0.ends_with(']') {
|
||||
if string_is_array(&self.0) {
|
||||
return self.deserialize_seq(visitor);
|
||||
}
|
||||
visitor.visit_string(self.0)
|
||||
|
|
@ -315,6 +315,7 @@ impl<'de> Deserializer<'de> for Value {
|
|||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
dbg!(&self);
|
||||
Err(SerdeParseError::new("seq", self.0.as_ref(), 0..0, "").into())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::entry::{Entry, ParseItem};
|
||||
use crate::entry::{string_is_array, Entry, ParseItem};
|
||||
use crate::error::{ExpectToken, NoValidTokenError, ResultExt, SerdeParseError};
|
||||
use crate::tokenizer::{SpannedToken, Tokenizer};
|
||||
use crate::{Token, VdfError};
|
||||
|
|
@ -127,7 +127,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||
if let Ok(float) = f64::from_str(str.as_ref()) {
|
||||
return visitor.visit_f64(float).ensure_span(span, self.source());
|
||||
}
|
||||
if str.starts_with('[') && str.ends_with(']') {
|
||||
if string_is_array(&str) {
|
||||
self.push_peeked(token);
|
||||
return self
|
||||
.deserialize_seq(visitor)
|
||||
|
|
@ -350,7 +350,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'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("]\"") {
|
||||
if (value_str.starts_with("\"[") && value_str.ends_with("]\""))
|
||||
|| (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;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
flex_array "[1.0 2.2]"
|
||||
tuple "[1 57]"
|
||||
single 1.2
|
||||
triple "[1.2 1.3 1.4]"
|
||||
triple "{1.2 1.3 1.4}"
|
||||
single_int 2
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue