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#[derive(Clone, PartialEq, Eq, Debug)]
20pub enum Entry {
21 Table(Table),
23
24 Array(Array),
26
27 Value(Value),
29
30 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 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 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 pub fn to<T: ParseItem>(self) -> Result<T, ParseEntryError> {
90 T::from_entry(self)
91 }
92
93 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 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 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 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 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 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
179pub trait ParseItem: Sized {
181 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 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 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}