vdf_reader/entry/
mod.rs

1mod array;
2mod statement;
3mod table;
4mod value;
5
6use crate::error::{ParseEntryError, ParseItemError, ParseStringError, UnknownError};
7use crate::{Item, VdfError};
8pub use array::Array;
9pub use statement::Statement;
10use std::any::type_name;
11use std::collections::HashMap;
12use std::fmt::Formatter;
13use std::mem::swap;
14use std::slice;
15pub use table::Table;
16pub use value::Value;
17
18/// The kinds of entry.
19#[derive(Clone, PartialEq, Eq, Debug)]
20pub enum Entry {
21    /// A table.
22    Table(Table),
23
24    /// An array (entries with the same key).
25    Array(Array),
26
27    /// A value.
28    Value(Value),
29
30    /// A statement (the values starting with #).
31    Statement(Statement),
32}
33
34impl Serialize for Entry {
35    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
36    where
37        S: Serializer,
38    {
39        match self {
40            Entry::Table(entry) => entry.serialize(serializer),
41            Entry::Array(entry) => entry.serialize(serializer),
42            Entry::Value(entry) => entry.serialize(serializer),
43            Entry::Statement(entry) => entry.serialize(serializer),
44        }
45    }
46}
47
48impl From<Item<'_>> for Entry {
49    fn from(item: Item) -> Self {
50        match item {
51            Item::Item { content, .. } => Entry::Value(content.into()),
52            Item::Statement { content, .. } => Entry::Statement(content.into()),
53        }
54    }
55}
56
57impl Entry {
58    /// Lookup an entry with a path.
59    pub fn lookup<S: AsRef<str>>(&self, path: S) -> Option<&Entry> {
60        let mut current = self;
61
62        for name in path.as_ref().split('.') {
63            if let Some(entry) = current.get(name.trim()) {
64                current = entry;
65            } else {
66                return None;
67            }
68        }
69
70        Some(current)
71    }
72
73    /// Try to get the named entry.
74    pub fn get<S: AsRef<str>>(&self, name: S) -> Option<&Entry> {
75        match self {
76            Entry::Table(value) => value.get(name.as_ref()),
77
78            Entry::Array(value) => name
79                .as_ref()
80                .parse::<usize>()
81                .ok()
82                .and_then(|i| value.get(i)),
83
84            _ => None,
85        }
86    }
87
88    /// Try to convert the entry to the given type.
89    pub fn to<T: ParseItem>(self) -> Result<T, ParseEntryError> {
90        T::from_entry(self)
91    }
92
93    /// Try to take the entry as a table.
94    pub fn as_table(&self) -> Option<&Table> {
95        if let Entry::Table(value) = self {
96            Some(value)
97        } else {
98            None
99        }
100    }
101
102    /// Try to take the entry as a slice.
103    pub fn as_slice(&self) -> Option<&[Entry]> {
104        if let Entry::Array(value) = self {
105            Some(value.as_slice())
106        } else {
107            unsafe { Some(slice::from_raw_parts(self, 1)) }
108        }
109    }
110
111    /// Try to take the entry as a statement.
112    pub fn as_statement(&self) -> Option<&Statement> {
113        if let Entry::Statement(value) = self {
114            Some(value)
115        } else {
116            None
117        }
118    }
119
120    /// Try to take the entry as a value.
121    pub fn as_value(&self) -> Option<&Value> {
122        if let Entry::Value(value) = self {
123            Some(value)
124        } else {
125            None
126        }
127    }
128
129    /// Try to take the entry as a string.
130    pub fn as_str(&self) -> Option<&str> {
131        match self {
132            Entry::Value(value) => Some(value),
133            Entry::Statement(value) => Some(value),
134            _ => None,
135        }
136    }
137
138    pub fn parse<'a, T: Deserialize<'a>>(&'a self) -> Result<T, ParseEntryError> {
139        let str = self
140            .as_str()
141            .ok_or_else(|| ParseEntryError::new(type_name::<T>(), self.clone()))?;
142        let mut deserializer = crate::serde::Deserializer::from_str(str);
143        let result = T::deserialize(&mut deserializer)
144            .map_err(|_| ParseEntryError::new(type_name::<T>(), self.clone()))?;
145        if deserializer.next().is_some() {
146            Err(ParseEntryError::new(type_name::<T>(), self.clone()))
147        } else {
148            Ok(result)
149        }
150    }
151
152    fn into_array(self) -> Result<Self, ParseEntryError> {
153        match self {
154            Entry::Array(array) => Ok(Entry::Array(array)),
155            Entry::Value(value) => {
156                let mut array = Array::default();
157                array.push(value.into());
158                Ok(Entry::Array(array))
159            }
160            entry => Err(ParseEntryError::new("array", entry)),
161        }
162    }
163
164    /// Try to take the entry as a slice.
165    pub fn push(&mut self, value: Entry) -> Result<(), ParseEntryError> {
166        let mut tmp = Entry::Value(Value::default());
167
168        swap(self, &mut tmp);
169        *self = tmp.into_array()?;
170        if let Entry::Array(array) = self {
171            array.push(value);
172        } else {
173            panic!("into_array ensured this is an array")
174        }
175        Ok(())
176    }
177}
178
179/// Parsable types.
180pub trait ParseItem: Sized {
181    /// Try to cast the entry into a concrete type
182    fn from_entry(entry: Entry) -> Result<Self, ParseEntryError> {
183        let string = match entry.as_str() {
184            Some(string) => string,
185            None => {
186                return Err(ParseEntryError::new(type_name::<Self>(), entry));
187            }
188        };
189        Self::from_str(string).map_err(|e| ParseEntryError::new(e.ty, entry))
190    }
191
192    /// Try to cast the item into a concrete type
193    fn from_item(item: Item) -> Result<Self, ParseItemError> {
194        Self::from_str(item.as_str()).map_err(|e| ParseItemError::new(e.ty, item))
195    }
196
197    /// Try to cast the string into a concrete type
198    fn from_str(item: &str) -> Result<Self, ParseStringError>;
199}
200
201macro_rules! from_str {
202	(for) => ();
203
204	(for $ty:ident $($rest:tt)*) => (
205		from_str!($ty);
206		from_str!(for $($rest)*);
207	);
208
209	($ty:ident) => (
210		impl ParseItem for $ty {
211			fn from_entry(entry: Entry) -> Result<Self, ParseEntryError> {
212                let string = match entry.as_str() {
213                    Some(string) => string,
214                    None => {
215                        return Err(ParseEntryError::new(type_name::<Self>(), entry));
216                    }
217                };
218				string.parse::<$ty>().map_err(|_| ParseEntryError::new(type_name::<Self>(), entry))
219			}
220
221            fn from_item(item: Item) -> Result<Self, ParseItemError> {
222                item.as_str().parse::<$ty>().map_err(|_| ParseItemError::new(type_name::<Self>(), item))
223            }
224
225            fn from_str(item: &str) -> Result<Self, ParseStringError> {
226                item.parse::<$ty>().map_err(|_| ParseStringError::new(type_name::<Self>(), item))
227            }
228		}
229	);
230}
231
232use crate::entry::array::{ArraySeq, TableArraySeq};
233use crate::entry::table::TableSeq;
234use serde_core::de::{
235    DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor,
236};
237use serde_core::{Deserialize, Deserializer, Serialize, Serializer};
238use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
239from_str!(for IpAddr Ipv4Addr Ipv6Addr SocketAddr SocketAddrV4 SocketAddrV6);
240from_str!(for i8 i16 i32 i64 isize u8 u16 u32 u64 usize f32 f64);
241
242impl ParseItem for bool {
243    fn from_str(item: &str) -> Result<Self, ParseStringError> {
244        match item {
245            "0" => Ok(false),
246            "1" => Ok(true),
247            v => v
248                .parse::<bool>()
249                .map_err(|_| ParseStringError::new(type_name::<Self>(), item)),
250        }
251    }
252}
253
254impl ParseItem for String {
255    fn from_entry(entry: Entry) -> Result<Self, ParseEntryError> {
256        match entry {
257            Entry::Table(entry) => Err(ParseEntryError::new(
258                type_name::<Self>(),
259                Entry::Table(entry),
260            )),
261            Entry::Array(entry) => Err(ParseEntryError::new(
262                type_name::<Self>(),
263                Entry::Array(entry),
264            )),
265            Entry::Statement(statement) => Ok(statement.into()),
266            Entry::Value(value) => Ok(value.into()),
267        }
268    }
269
270    fn from_item(item: Item) -> Result<Self, ParseItemError> {
271        Ok(item.into_content().into())
272    }
273
274    fn from_str(item: &str) -> Result<Self, ParseStringError> {
275        Ok(item.into())
276    }
277}
278
279impl<T: ParseItem> ParseItem for Option<T> {
280    fn from_entry(entry: Entry) -> Result<Self, ParseEntryError> {
281        T::from_entry(entry).map(Some)
282    }
283
284    fn from_item(item: Item) -> Result<Self, ParseItemError> {
285        T::from_item(item).map(Some)
286    }
287
288    fn from_str(item: &str) -> Result<Self, ParseStringError> {
289        T::from_str(item).map(Some)
290    }
291}
292
293impl<'de> Deserialize<'de> for Entry {
294    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
295    where
296        D: Deserializer<'de>,
297    {
298        struct EntryVisitor;
299
300        impl<'v> Visitor<'v> for EntryVisitor {
301            type Value = Entry;
302
303            fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
304                write!(formatter, "any string like value or group")
305            }
306
307            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
308            where
309                E: Error,
310            {
311                Ok(Entry::Value(v.to_string().into()))
312            }
313
314            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
315            where
316                E: Error,
317            {
318                Ok(Entry::Value(v.to_string().into()))
319            }
320
321            fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
322            where
323                E: Error,
324            {
325                Ok(Entry::Value(v.to_string().into()))
326            }
327
328            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
329            where
330                E: Error,
331            {
332                if v.starts_with('#') {
333                    Ok(Entry::Statement(v.to_string().into()))
334                } else {
335                    Ok(Entry::Value(v.to_string().into()))
336                }
337            }
338
339            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
340            where
341                E: Error,
342            {
343                if v.starts_with('#') {
344                    Ok(Entry::Statement(v.into()))
345                } else {
346                    Ok(Entry::Value(v.into()))
347                }
348            }
349
350            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
351            where
352                E: Error,
353            {
354                let v = if v { "1" } else { "0" };
355                Ok(Entry::Value(v.to_string().into()))
356            }
357
358            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
359            where
360                A: MapAccess<'v>,
361            {
362                let mut res = HashMap::new();
363
364                while let Some(entry) = map.next_entry()? {
365                    res.insert(entry.0, entry.1);
366                }
367
368                Ok(Entry::Table(res.into()))
369            }
370
371            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
372            where
373                A: SeqAccess<'v>,
374            {
375                let mut res = Vec::new();
376
377                while let Some(entry) = seq.next_element()? {
378                    res.push(entry);
379                }
380
381                Ok(Entry::Array(res.into()))
382            }
383        }
384
385        deserializer.deserialize_any(EntryVisitor)
386    }
387}
388
389impl<'de> Deserializer<'de> for Entry {
390    type Error = VdfError;
391
392    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
393    where
394        V: Visitor<'de>,
395    {
396        match self {
397            Entry::Table(table) => visitor.visit_map(TableSeq::new(table)),
398            Entry::Array(array) => visitor.visit_seq(ArraySeq::new(array)),
399            Entry::Value(val) => val.deserialize_any(visitor),
400            Entry::Statement(val) => visitor.visit_string(val.into()),
401        }
402    }
403
404    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
405    where
406        V: Visitor<'de>,
407    {
408        match self {
409            Entry::Value(val) => val.deserialize_bool(visitor),
410            Entry::Statement(val) => Value::from(val).deserialize_bool(visitor),
411            _ => Err(UnknownError::from("bool").into()),
412        }
413    }
414
415    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
416    where
417        V: Visitor<'de>,
418    {
419        match self {
420            Entry::Value(val) => val.deserialize_i8(visitor),
421            Entry::Statement(val) => Value::from(val).deserialize_i8(visitor),
422            _ => Err(UnknownError::from("i8").into()),
423        }
424    }
425
426    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
427    where
428        V: Visitor<'de>,
429    {
430        match self {
431            Entry::Value(val) => val.deserialize_i16(visitor),
432            Entry::Statement(val) => Value::from(val).deserialize_i16(visitor),
433            _ => Err(UnknownError::from("i16").into()),
434        }
435    }
436
437    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
438    where
439        V: Visitor<'de>,
440    {
441        match self {
442            Entry::Value(val) => val.deserialize_i32(visitor),
443            Entry::Statement(val) => Value::from(val).deserialize_i32(visitor),
444            _ => Err(UnknownError::from("i32").into()),
445        }
446    }
447
448    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
449    where
450        V: Visitor<'de>,
451    {
452        match self {
453            Entry::Value(val) => val.deserialize_i64(visitor),
454            Entry::Statement(val) => Value::from(val).deserialize_i64(visitor),
455            _ => Err(UnknownError::from("i64").into()),
456        }
457    }
458
459    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
460    where
461        V: Visitor<'de>,
462    {
463        match self {
464            Entry::Value(val) => val.deserialize_u8(visitor),
465            Entry::Statement(val) => Value::from(val).deserialize_u8(visitor),
466            _ => Err(UnknownError::from("u8").into()),
467        }
468    }
469
470    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
471    where
472        V: Visitor<'de>,
473    {
474        match self {
475            Entry::Value(val) => val.deserialize_u16(visitor),
476            Entry::Statement(val) => Value::from(val).deserialize_u16(visitor),
477            _ => Err(UnknownError::from("u16").into()),
478        }
479    }
480
481    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
482    where
483        V: Visitor<'de>,
484    {
485        match self {
486            Entry::Value(val) => val.deserialize_u32(visitor),
487            Entry::Statement(val) => Value::from(val).deserialize_u32(visitor),
488            _ => Err(UnknownError::from("u32").into()),
489        }
490    }
491
492    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
493    where
494        V: Visitor<'de>,
495    {
496        match self {
497            Entry::Value(val) => val.deserialize_u64(visitor),
498            Entry::Statement(val) => Value::from(val).deserialize_u64(visitor),
499            _ => Err(UnknownError::from("u64").into()),
500        }
501    }
502
503    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
504    where
505        V: Visitor<'de>,
506    {
507        match self {
508            Entry::Value(val) => val.deserialize_f32(visitor),
509            Entry::Statement(val) => Value::from(val).deserialize_f32(visitor),
510            _ => Err(UnknownError::from("f32").into()),
511        }
512    }
513
514    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
515    where
516        V: Visitor<'de>,
517    {
518        match self {
519            Entry::Value(val) => val.deserialize_f64(visitor),
520            Entry::Statement(val) => Value::from(val).deserialize_f64(visitor),
521            _ => Err(UnknownError::from("f64").into()),
522        }
523    }
524
525    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
526    where
527        V: Visitor<'de>,
528    {
529        match self {
530            Entry::Value(val) => val.deserialize_char(visitor),
531            Entry::Statement(val) => Value::from(val).deserialize_char(visitor),
532            _ => Err(UnknownError::from("char").into()),
533        }
534    }
535
536    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
537    where
538        V: Visitor<'de>,
539    {
540        match self {
541            Entry::Value(val) => val.deserialize_str(visitor),
542            Entry::Statement(val) => Value::from(val).deserialize_str(visitor),
543            _ => Err(UnknownError::from("str").into()),
544        }
545    }
546
547    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
548    where
549        V: Visitor<'de>,
550    {
551        match self {
552            Entry::Value(val) => val.deserialize_string(visitor),
553            Entry::Statement(val) => Value::from(val).deserialize_string(visitor),
554            _ => Err(UnknownError::from("string1").into()),
555        }
556    }
557
558    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
559    where
560        V: Visitor<'de>,
561    {
562        match self {
563            Entry::Value(val) => val.deserialize_bytes(visitor),
564            _ => Err(UnknownError::from("bytes").into()),
565        }
566    }
567
568    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
569    where
570        V: Visitor<'de>,
571    {
572        match self {
573            Entry::Value(val) => val.deserialize_bool(visitor),
574            _ => Err(UnknownError::from("bytes buf").into()),
575        }
576    }
577
578    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
579    where
580        V: Visitor<'de>,
581    {
582        match self {
583            Entry::Value(val) => val.deserialize_option(visitor),
584            Entry::Statement(val) => Value::from(val).deserialize_option(visitor),
585            _ => Err(UnknownError::from("option").into()),
586        }
587    }
588
589    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
590    where
591        V: Visitor<'de>,
592    {
593        match self {
594            Entry::Value(val) => val.deserialize_unit(visitor),
595            Entry::Statement(val) => Value::from(val).deserialize_unit(visitor),
596            _ => Err(UnknownError::from("unit").into()),
597        }
598    }
599
600    fn deserialize_unit_struct<V>(
601        self,
602        name: &'static str,
603        visitor: V,
604    ) -> Result<V::Value, Self::Error>
605    where
606        V: Visitor<'de>,
607    {
608        match self {
609            Entry::Value(val) => val.deserialize_unit_struct(name, visitor),
610            Entry::Statement(val) => Value::from(val).deserialize_unit_struct(name, visitor),
611            _ => Err(UnknownError::from("unit_struct").into()),
612        }
613    }
614
615    fn deserialize_newtype_struct<V>(
616        self,
617        _name: &'static str,
618        _visitor: V,
619    ) -> Result<V::Value, Self::Error>
620    where
621        V: Visitor<'de>,
622    {
623        todo!()
624    }
625
626    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
627    where
628        V: Visitor<'de>,
629    {
630        match self {
631            Entry::Array(arr) => visitor.visit_seq(ArraySeq::new(arr)),
632            Entry::Table(table) => visitor.visit_seq(TableArraySeq::new(table)),
633            _ => Err(UnknownError::from("array").into()),
634        }
635    }
636
637    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
638    where
639        V: Visitor<'de>,
640    {
641        match self {
642            Entry::Array(arr) => visitor.visit_seq(ArraySeq::new(arr)),
643            _ => Err(UnknownError::from("tuple").into()),
644        }
645    }
646
647    fn deserialize_tuple_struct<V>(
648        self,
649        _name: &'static str,
650        _len: usize,
651        visitor: V,
652    ) -> Result<V::Value, Self::Error>
653    where
654        V: Visitor<'de>,
655    {
656        match self {
657            Entry::Array(arr) => visitor.visit_seq(ArraySeq::new(arr)),
658            _ => Err(UnknownError::from("tuple_struct").into()),
659        }
660    }
661
662    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
663    where
664        V: Visitor<'de>,
665    {
666        match self {
667            Entry::Table(table) => visitor.visit_map(TableSeq::new(table)),
668            _ => Err(UnknownError::from("map").into()),
669        }
670    }
671
672    fn deserialize_struct<V>(
673        self,
674        _name: &'static str,
675        _fields: &'static [&'static str],
676        visitor: V,
677    ) -> Result<V::Value, Self::Error>
678    where
679        V: Visitor<'de>,
680    {
681        self.deserialize_map(visitor)
682    }
683
684    fn deserialize_enum<V>(
685        self,
686        _name: &'static str,
687        _variants: &'static [&'static str],
688        visitor: V,
689    ) -> Result<V::Value, Self::Error>
690    where
691        V: Visitor<'de>,
692    {
693        struct EnVarAccess {
694            variant: Value,
695            value: Entry,
696        }
697        struct EnValAccess {
698            value: Entry,
699        }
700
701        impl<'de> EnumAccess<'de> for EnVarAccess {
702            type Error = VdfError;
703            type Variant = EnValAccess;
704
705            fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
706            where
707                V: DeserializeSeed<'de>,
708            {
709                seed.deserialize(self.variant)
710                    .map(|v| (v, EnValAccess { value: self.value }))
711            }
712        }
713
714        impl<'de> VariantAccess<'de> for EnValAccess {
715            type Error = VdfError;
716
717            fn unit_variant(self) -> Result<(), Self::Error> {
718                Err(UnknownError::from("unit").into())
719            }
720
721            fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
722            where
723                T: DeserializeSeed<'de>,
724            {
725                seed.deserialize(self.value)
726            }
727
728            fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
729            where
730                V: Visitor<'de>,
731            {
732                self.value.deserialize_seq(visitor)
733            }
734
735            fn struct_variant<V>(
736                self,
737                _fields: &'static [&'static str],
738                visitor: V,
739            ) -> Result<V::Value, Self::Error>
740            where
741                V: Visitor<'de>,
742            {
743                self.value.deserialize_map(visitor)
744            }
745        }
746
747        match self {
748            Entry::Table(table) if table.len() == 1 => {
749                let (variant, value) = HashMap::from(table).into_iter().next().unwrap();
750                visitor.visit_enum(EnVarAccess {
751                    variant: variant.into(),
752                    value,
753                })
754            }
755            _ => Err(UnknownError::from("enum").into()),
756        }
757    }
758
759    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
760    where
761        V: Visitor<'de>,
762    {
763        self.deserialize_string(visitor)
764    }
765
766    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
767    where
768        V: Visitor<'de>,
769    {
770        self.deserialize_any(visitor)
771    }
772}
773
774#[cfg(test)]
775#[track_caller]
776fn unwrap_err<T>(r: Result<T, crate::VdfError>) -> T {
777    r.map_err(miette::Error::from).unwrap()
778}
779
780#[test]
781fn test_serde_entry() {
782    use maplit::hashmap;
783
784    let j = r#"1"#;
785    assert_eq!(Entry::Value("1".into()), unwrap_err(crate::from_str(j)));
786
787    let j = r#""foo bar""#;
788    assert_eq!(
789        Entry::Value("foo bar".into()),
790        unwrap_err(crate::from_str(j))
791    );
792
793    let j = r#"{foo bar}"#;
794
795    assert_eq!(
796        Entry::Table(hashmap! {"foo".into() => Entry::Value("bar".into())}.into()),
797        unwrap_err(crate::from_str(j))
798    );
799
800    let j = r#""[1 2 3]""#;
801
802    assert_eq!(
803        Entry::Array(
804            vec![
805                Value::from("1").into(),
806                Value::from("2").into(),
807                Value::from("3").into()
808            ]
809            .into()
810        ),
811        unwrap_err(crate::from_str(j))
812    );
813
814    let j = r#""{1 2 3}""#;
815
816    assert_eq!(
817        Entry::Array(
818            vec![
819                Value::from("1").into(),
820                Value::from("2").into(),
821                Value::from("3").into()
822            ]
823            .into()
824        ),
825        unwrap_err(crate::from_str(j))
826    );
827}
828
829#[test]
830fn test_parse_entry() {
831    assert_eq!(1, Entry::Value("1".into()).parse::<usize>().unwrap());
832    assert_eq!(
833        vec!(1, 2, 3),
834        Entry::Value("1 2 3".into()).parse::<Vec<u8>>().unwrap()
835    );
836    assert_eq!(
837        (1, 2, 3),
838        Entry::Value("1 2 3".into())
839            .parse::<(u8, u8, u8)>()
840            .unwrap()
841    );
842}
843
844pub(crate) fn string_is_array(string: &str) -> bool {
845    (string.starts_with('[') && string.ends_with(']'))
846        || (string.starts_with('{') && string.ends_with('}'))
847}