1use crate::{Duration, Time};
2use itertools::Itertools;
3use serde_derive::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::convert::{TryFrom, TryInto};
6use std::fmt;
7use std::fmt::{Display, Formatter};
8use std::iter::FromIterator;
9
10pub type MessageValue = HashMap<String, Value>;
12
13#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
15pub enum Value {
16 Bool(bool),
18 I8(i8),
20 I16(i16),
22 I32(i32),
24 I64(i64),
26 U8(u8),
28 U16(u16),
30 U32(u32),
32 U64(u64),
34 F32(f32),
36 F64(f64),
38 String(String),
40 Time(Time),
42 Duration(Duration),
44 Array(Vec<Value>),
48 Message(MessageValue),
50}
51
52impl Value {
53 fn fmt_indented(&self, indentation: usize, step: usize, f: &mut Formatter<'_>) -> fmt::Result {
54 match self {
55 Value::Bool(v) => v.fmt(f),
56 Value::I8(v) => v.fmt(f),
57 Value::I16(v) => v.fmt(f),
58 Value::I32(v) => v.fmt(f),
59 Value::I64(v) => v.fmt(f),
60 Value::U8(v) => v.fmt(f),
61 Value::U16(v) => v.fmt(f),
62 Value::U32(v) => v.fmt(f),
63 Value::U64(v) => v.fmt(f),
64 Value::F32(v) => v.fmt(f),
65 Value::F64(v) => v.fmt(f),
66 Value::String(v) => write!(f, "{:?}", v),
67 Value::Time(v) => v.fmt(f),
68 Value::Duration(v) => v.fmt(f),
69 Value::Array(items) => {
70 for item in items {
71 writeln!(f)?;
72 write!(f, "{:indent$}- ", "", indent = indentation)?;
73 item.fmt_indented(indentation + step, step, f)?;
74 }
75 Ok(())
76 }
77 Value::Message(items) => {
78 for (key, item) in items.iter().sorted_by(|a, b| Ord::cmp(&a.0, &b.0)) {
79 writeln!(f)?;
80 write!(f, "{:indent$}{}: ", "", key, indent = indentation)?;
81 item.fmt_indented(indentation + step, step, f)?;
82 }
83 Ok(())
84 }
85 }
86 }
87
88 pub fn as_bool(&self) -> Option<bool> {
99 if let Value::Bool(value) = self {
100 Some(*value)
101 } else {
102 None
103 }
104 }
105
106 pub fn as_i8(&self) -> Option<i8> {
116 if let Value::I8(value) = self {
117 Some(*value)
118 } else {
119 None
120 }
121 }
122
123 pub fn as_i16(&self) -> Option<i16> {
133 if let Value::I16(value) = self {
134 Some(*value)
135 } else {
136 None
137 }
138 }
139
140 pub fn as_i32(&self) -> Option<i32> {
150 if let Value::I32(value) = self {
151 Some(*value)
152 } else {
153 None
154 }
155 }
156
157 pub fn as_i64(&self) -> Option<i64> {
167 if let Value::I64(value) = self {
168 Some(*value)
169 } else {
170 None
171 }
172 }
173
174 pub fn as_u8(&self) -> Option<u8> {
184 if let Value::U8(value) = self {
185 Some(*value)
186 } else {
187 None
188 }
189 }
190
191 pub fn as_u16(&self) -> Option<u16> {
201 if let Value::U16(value) = self {
202 Some(*value)
203 } else {
204 None
205 }
206 }
207
208 pub fn as_u32(&self) -> Option<u32> {
218 if let Value::U32(value) = self {
219 Some(*value)
220 } else {
221 None
222 }
223 }
224
225 pub fn as_u64(&self) -> Option<u64> {
235 if let Value::U64(value) = self {
236 Some(*value)
237 } else {
238 None
239 }
240 }
241
242 pub fn as_f32(&self) -> Option<f32> {
252 if let Value::F32(value) = self {
253 Some(*value)
254 } else {
255 None
256 }
257 }
258
259 pub fn as_f64(&self) -> Option<f64> {
269 if let Value::F64(value) = self {
270 Some(*value)
271 } else {
272 None
273 }
274 }
275
276 pub fn as_str(&self) -> Option<&str> {
286 if let Value::String(value) = self {
287 Some(value)
288 } else {
289 None
290 }
291 }
292
293 pub fn try_into_string(self) -> Option<String> {
303 if let Value::String(value) = self {
304 Some(value)
305 } else {
306 None
307 }
308 }
309
310 pub fn as_time(&self) -> Option<Time> {
323 if let Value::Time(value) = self {
324 Some(*value)
325 } else {
326 None
327 }
328 }
329
330 pub fn as_duration(&self) -> Option<Duration> {
343 if let Value::Duration(value) = self {
344 Some(*value)
345 } else {
346 None
347 }
348 }
349
350 pub fn as_slice(&self) -> Option<&[Value]> {
363 if let Value::Array(value) = self {
364 Some(value)
365 } else {
366 None
367 }
368 }
369
370 pub fn try_into_vec(self) -> Option<Vec<Value>> {
383 if let Value::Array(value) = self {
384 Some(value)
385 } else {
386 None
387 }
388 }
389
390 pub fn as_map(&self) -> Option<&MessageValue> {
404 if let Value::Message(value) = self {
405 Some(value)
406 } else {
407 None
408 }
409 }
410
411 pub fn try_into_map(self) -> Option<MessageValue> {
425 if let Value::Message(value) = self {
426 Some(value)
427 } else {
428 None
429 }
430 }
431}
432
433impl Display for Value {
434 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
435 self.fmt_indented(0, 2, f)
436 }
437}
438
439impl From<bool> for Value {
440 fn from(v: bool) -> Self {
441 Self::Bool(v)
442 }
443}
444
445impl From<i8> for Value {
446 fn from(v: i8) -> Self {
447 Self::I8(v)
448 }
449}
450
451impl From<i16> for Value {
452 fn from(v: i16) -> Self {
453 Self::I16(v)
454 }
455}
456
457impl From<i32> for Value {
458 fn from(v: i32) -> Self {
459 Self::I32(v)
460 }
461}
462
463impl From<i64> for Value {
464 fn from(v: i64) -> Self {
465 Self::I64(v)
466 }
467}
468
469impl From<u8> for Value {
470 fn from(v: u8) -> Self {
471 Self::U8(v)
472 }
473}
474
475impl From<u16> for Value {
476 fn from(v: u16) -> Self {
477 Self::U16(v)
478 }
479}
480
481impl From<u32> for Value {
482 fn from(v: u32) -> Self {
483 Self::U32(v)
484 }
485}
486
487impl From<u64> for Value {
488 fn from(v: u64) -> Self {
489 Self::U64(v)
490 }
491}
492
493impl From<f32> for Value {
494 fn from(v: f32) -> Self {
495 Self::F32(v)
496 }
497}
498
499impl From<f64> for Value {
500 fn from(v: f64) -> Self {
501 Self::F64(v)
502 }
503}
504
505impl From<String> for Value {
506 fn from(v: String) -> Self {
507 Self::String(v)
508 }
509}
510
511impl From<Time> for Value {
512 fn from(v: Time) -> Self {
513 Self::Time(v)
514 }
515}
516
517impl From<Duration> for Value {
518 fn from(v: Duration) -> Self {
519 Self::Duration(v)
520 }
521}
522
523impl<T: Into<Value>> From<Vec<T>> for Value {
524 fn from(v: Vec<T>) -> Self {
525 Self::Array(v.into_iter().map(Into::into).collect())
526 }
527}
528
529impl<T: Into<Value>, const L: usize> From<[T; L]> for Value {
530 fn from(v: [T; L]) -> Self {
531 Self::Array(IntoIterator::into_iter(v).map(Into::into).collect())
532 }
533}
534
535impl From<HashMap<String, Value>> for Value {
536 fn from(v: HashMap<String, Value>) -> Self {
537 Self::Message(v)
538 }
539}
540
541impl TryFrom<Value> for bool {
542 type Error = ();
543
544 fn try_from(value: Value) -> Result<Self, Self::Error> {
545 value.as_bool().ok_or(())
546 }
547}
548
549impl TryFrom<Value> for i8 {
550 type Error = ();
551
552 fn try_from(value: Value) -> Result<Self, Self::Error> {
553 value.as_i8().ok_or(())
554 }
555}
556
557impl TryFrom<Value> for i16 {
558 type Error = ();
559
560 fn try_from(value: Value) -> Result<Self, Self::Error> {
561 value.as_i16().ok_or(())
562 }
563}
564
565impl TryFrom<Value> for i32 {
566 type Error = ();
567
568 fn try_from(value: Value) -> Result<Self, Self::Error> {
569 value.as_i32().ok_or(())
570 }
571}
572
573impl TryFrom<Value> for i64 {
574 type Error = ();
575
576 fn try_from(value: Value) -> Result<Self, Self::Error> {
577 value.as_i64().ok_or(())
578 }
579}
580
581impl TryFrom<Value> for u8 {
582 type Error = ();
583
584 fn try_from(value: Value) -> Result<Self, Self::Error> {
585 value.as_u8().ok_or(())
586 }
587}
588
589impl TryFrom<Value> for u16 {
590 type Error = ();
591
592 fn try_from(value: Value) -> Result<Self, Self::Error> {
593 value.as_u16().ok_or(())
594 }
595}
596
597impl TryFrom<Value> for u32 {
598 type Error = ();
599
600 fn try_from(value: Value) -> Result<Self, Self::Error> {
601 value.as_u32().ok_or(())
602 }
603}
604
605impl TryFrom<Value> for u64 {
606 type Error = ();
607
608 fn try_from(value: Value) -> Result<Self, Self::Error> {
609 value.as_u64().ok_or(())
610 }
611}
612
613impl TryFrom<Value> for f32 {
614 type Error = ();
615
616 fn try_from(value: Value) -> Result<Self, Self::Error> {
617 value.as_f32().ok_or(())
618 }
619}
620
621impl TryFrom<Value> for f64 {
622 type Error = ();
623
624 fn try_from(value: Value) -> Result<Self, Self::Error> {
625 value.as_f64().ok_or(())
626 }
627}
628
629impl TryFrom<Value> for String {
630 type Error = ();
631
632 fn try_from(value: Value) -> Result<Self, Self::Error> {
633 value.try_into_string().ok_or(())
634 }
635}
636
637impl TryFrom<Value> for Time {
638 type Error = ();
639
640 fn try_from(value: Value) -> Result<Self, Self::Error> {
641 value.as_time().ok_or(())
642 }
643}
644
645impl TryFrom<Value> for Duration {
646 type Error = ();
647
648 fn try_from(value: Value) -> Result<Self, Self::Error> {
649 value.as_duration().ok_or(())
650 }
651}
652
653impl<T: TryFrom<Value>> TryFrom<Value> for Vec<T> {
654 type Error = ();
655
656 fn try_from(value: Value) -> Result<Self, Self::Error> {
657 let value = value.try_into_vec().ok_or(())?;
658 value
659 .into_iter()
660 .map(TryInto::try_into)
661 .collect::<Result<Self, _>>()
662 .map_err(|_| ())
663 }
664}
665
666impl<T: TryFrom<Value>, const L: usize> TryFrom<Value> for [T; L] {
667 type Error = ();
668
669 fn try_from(value: Value) -> Result<Self, Self::Error> {
670 let value = value.try_into_vec().ok_or(())?;
671 if value.len() != L {
672 return Err(());
673 }
674 array_init::from_iter(value.into_iter().filter_map(|v| v.try_into().ok())).ok_or(())
675 }
676}
677
678impl TryFrom<Value> for HashMap<String, Value> {
679 type Error = ();
680
681 fn try_from(value: Value) -> Result<Self, Self::Error> {
682 value.try_into_map().ok_or(())
683 }
684}
685
686impl<K: Into<String>, T: Into<Value>> FromIterator<(K, T)> for Value {
687 fn from_iter<I: IntoIterator<Item = (K, T)>>(iter: I) -> Self {
688 Self::Message(
689 iter.into_iter()
690 .map(|(key, value)| (key.into(), value.into()))
691 .collect(),
692 )
693 }
694}
695
696impl<T: Into<Value>> FromIterator<T> for Value {
697 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
698 Self::Array(iter.into_iter().map(Into::into).collect())
699 }
700}