valuable/
value.rs

1use crate::{Enumerable, Listable, Mappable, Structable, Tuplable, Valuable, Visit};
2
3use core::fmt;
4
5macro_rules! value {
6    (
7        $(
8            $(#[$attrs:meta])*
9            $variant:ident($ty:ty),
10        )*
11    ) => {
12        /// Any Rust value
13        ///
14        /// The `Value` enum is used to pass single values to the
15        /// [visitor][`Visit`]. Primitive types are enumerated and other types
16        /// are represented at trait objects.
17        ///
18        /// Values are converted to `Value` instances using
19        /// [`Valuable::as_value()`].
20        ///
21        /// # Examples
22        ///
23        /// Convert a primitive type
24        ///
25        /// ```
26        /// use valuable::{Value, Valuable};
27        ///
28        /// let num = 123;
29        /// let val = num.as_value();
30        ///
31        /// assert!(matches!(val, Value::I32(v) if v == 123));
32        /// ```
33        ///
34        /// Converting a struct
35        ///
36        /// ```
37        /// use valuable::{Value, Valuable};
38        ///
39        /// #[derive(Valuable, Debug)]
40        /// struct HelloWorld {
41        ///     message: String,
42        /// }
43        ///
44        /// let hello = HelloWorld {
45        ///     message: "greetings".to_string(),
46        /// };
47        ///
48        /// let val = hello.as_value();
49        ///
50        /// assert!(matches!(val, Value::Structable(_v)));
51        ///
52        /// // The Value `Debug` output matches the struct's
53        /// assert_eq!(
54        ///     format!("{:?}", val),
55        ///     format!("{:?}", hello),
56        /// );
57        /// ```
58        ///
59        /// [visitor]: Visit
60        #[non_exhaustive]
61        #[derive(Clone, Copy)]
62        pub enum Value<'a> {
63            $(
64                $(#[$attrs])*
65                $variant($ty),
66            )*
67
68            /// A Rust `()` or `None` value.
69            ///
70            /// # Examples
71            ///
72            /// ```
73            /// use valuable::Value;
74            ///
75            /// let v = Value::Unit;
76            /// ```
77            Unit,
78        }
79
80        $(
81            $(#[$attrs])*
82            impl<'a> From<$ty> for Value<'a> {
83                fn from(src: $ty) -> Value<'a> {
84                    Value::$variant(src)
85                }
86            }
87        )*
88
89        impl<'a> From<()> for Value<'a> {
90            fn from(_: ()) -> Value<'a> {
91                Value::Tuplable(&())
92            }
93        }
94
95        impl fmt::Debug for Value<'_> {
96            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
97                use Value::*;
98
99                // Doc comments are expanded into the branch arms, which results
100                // in a warning. It isn't a big deal, so silence it.
101                #[allow(unused_doc_comments)]
102                match self {
103                    $(
104                        $(#[$attrs])*
105                        $variant(v) => fmt::Debug::fmt(v, fmt),
106                    )*
107                    Unit => ().fmt(fmt),
108                }
109            }
110        }
111    }
112}
113
114value! {
115    /// A Rust `bool` value
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use valuable::Value;
121    ///
122    /// let v = Value::Bool(true);
123    /// ```
124    Bool(bool),
125
126    /// A Rust `char` value
127    ///
128    /// # Examples
129    ///
130    /// ```
131    /// use valuable::Value;
132    ///
133    /// let v = Value::Char('h');
134    /// ```
135    Char(char),
136
137    /// A Rust `f32` value
138    ///
139    /// # Examples
140    ///
141    /// ```
142    /// use valuable::Value;
143    ///
144    /// let v = Value::F32(3.1415);
145    /// ```
146    F32(f32),
147
148    /// A Rust `f64` value
149    ///
150    /// # Examples
151    ///
152    /// ```
153    /// use valuable::Value;
154    ///
155    /// let v = Value::F64(3.1415);
156    /// ```
157    F64(f64),
158
159    /// A Rust `i8` value
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use valuable::Value;
165    ///
166    /// let v = Value::I8(42);
167    /// ```
168    I8(i8),
169
170    /// A Rust `i16` value
171    ///
172    /// # Examples
173    ///
174    /// ```
175    /// use valuable::Value;
176    ///
177    /// let v = Value::I16(42);
178    /// ```
179    I16(i16),
180
181    /// A Rust `i32` value
182    ///
183    /// # Examples
184    ///
185    /// ```
186    /// use valuable::Value;
187    ///
188    /// let v = Value::I32(42);
189    /// ```
190    I32(i32),
191
192    /// A Rust `i64` value
193    ///
194    /// # Examples
195    ///
196    /// ```
197    /// use valuable::Value;
198    ///
199    /// let v = Value::I64(42);
200    /// ```
201    I64(i64),
202
203    /// A Rust `i128` value
204    ///
205    /// # Examples
206    ///
207    /// ```
208    /// use valuable::Value;
209    ///
210    /// let v = Value::I128(42);
211    /// ```
212    I128(i128),
213
214    /// A Rust `isize` value
215    ///
216    /// # Examples
217    ///
218    /// ```
219    /// use valuable::Value;
220    ///
221    /// let v = Value::Isize(42);
222    /// ```
223    Isize(isize),
224
225    /// A Rust `&str` value
226    ///
227    /// # Examples
228    ///
229    /// ```
230    /// use valuable::Value;
231    ///
232    /// let v = Value::String("hello");
233    /// ```
234    String(&'a str),
235
236    /// A Rust `u8` value
237    ///
238    /// # Examples
239    ///
240    /// ```
241    /// use valuable::Value;
242    ///
243    /// let v = Value::U8(42);
244    /// ```
245    U8(u8),
246
247    /// A Rust `u16` value
248    ///
249    /// # Examples
250    ///
251    /// ```
252    /// use valuable::Value;
253    ///
254    /// let v = Value::U16(42);
255    /// ```
256    U16(u16),
257
258    /// A Rust `u32` value
259    ///
260    /// # Examples
261    ///
262    /// ```
263    /// use valuable::Value;
264    ///
265    /// let v = Value::U32(42);
266    /// ```
267    U32(u32),
268
269    /// A Rust `u64` value
270    ///
271    /// # Examples
272    ///
273    /// ```
274    /// use valuable::Value;
275    ///
276    /// let v = Value::U64(42);
277    /// ```
278    U64(u64),
279
280    /// A Rust `u128` value
281    ///
282    /// # Examples
283    ///
284    /// ```
285    /// use valuable::Value;
286    ///
287    /// let v = Value::U128(42);
288    /// ```
289    U128(u128),
290
291    /// A Rust `usize` value
292    ///
293    /// # Examples
294    ///
295    /// ```
296    /// use valuable::Value;
297    ///
298    /// let v = Value::Usize(42);
299    /// ```
300    Usize(usize),
301
302    /// A Rust `&Path` value
303    ///
304    /// # Examples
305    ///
306    /// ```
307    /// use valuable::Value;
308    /// use std::path::Path;
309    ///
310    /// let path = Path::new("a.txt");
311    /// let v = Value::Path(path);
312    /// ```
313    #[cfg(feature = "std")]
314    Path(&'a std::path::Path),
315
316    /// A Rust error value
317    ///
318    /// # Examples
319    ///
320    /// ```
321    /// use valuable::Value;
322    /// use std::io;
323    ///
324    /// let err: io::Error = io::ErrorKind::Other.into();
325    /// let v = Value::Error(&err);
326    /// ```
327    #[cfg(feature = "std")]
328    Error(&'a (dyn std::error::Error +'static)),
329
330    /// A Rust list value
331    ///
332    /// # Examples
333    ///
334    /// ```
335    /// use valuable::Value;
336    ///
337    /// let vals = vec![1, 2, 3, 4, 5];
338    /// let v = Value::Listable(&vals);
339    /// ```
340    Listable(&'a dyn Listable),
341
342    /// A Rust map value
343    ///
344    /// # Examples
345    ///
346    /// ```
347    /// use valuable::Value;
348    /// use std::collections::HashMap;
349    ///
350    /// let mut map = HashMap::new();
351    /// map.insert("foo", 1);
352    /// map.insert("bar", 2);
353    ///
354    /// let v = Value::Mappable(&map);
355    /// ```
356    Mappable(&'a dyn Mappable),
357
358    /// A Rust struct value
359    ///
360    /// # Examples
361    ///
362    /// ```
363    /// use valuable::{Value, Valuable};
364    ///
365    /// #[derive(Valuable)]
366    /// struct MyStruct {
367    ///     field: u32,
368    /// }
369    ///
370    /// let my_struct = MyStruct {
371    ///     field: 123,
372    /// };
373    ///
374    /// let v = Value::Structable(&my_struct);
375    /// ```
376    Structable(&'a dyn Structable),
377
378    /// A Rust enum value
379    ///
380    /// # Examples
381    ///
382    /// ```
383    /// use valuable::{Value, Valuable};
384    ///
385    /// #[derive(Valuable)]
386    /// enum MyEnum {
387    ///     Foo,
388    ///     Bar,
389    /// }
390    ///
391    /// let my_enum = MyEnum::Foo;
392    /// let v = Value::Enumerable(&my_enum);
393    /// ```
394    Enumerable(&'a dyn Enumerable),
395
396    /// A tuple value
397    ///
398    /// # Examples
399    ///
400    /// ```
401    /// use valuable::{Value, Valuable};
402    ///
403    /// let my_tuple = (123, 456);
404    /// let v = Value::Tuplable(&my_tuple);
405    /// ```
406    Tuplable(&'a dyn Tuplable),
407}
408
409impl Valuable for Value<'_> {
410    fn as_value(&self) -> Value<'_> {
411        *self
412    }
413
414    fn visit(&self, visit: &mut dyn Visit) {
415        visit.visit_value(*self);
416    }
417}
418
419impl Default for Value<'_> {
420    fn default() -> Self {
421        Value::Unit
422    }
423}
424
425macro_rules! convert {
426    (
427        $(
428            $(#[$attrs:meta])*
429            $ty:ty => $as:ident,
430        )*
431    ) => {
432        impl<'a> Value<'a> {
433            /// Return a `bool` representation of `self`, if possible.
434            ///
435            /// # Examples
436            ///
437            /// ```
438            /// use valuable::Value;
439            ///
440            /// assert_eq!(Value::Bool(true).as_bool(), Some(true));
441            /// assert_eq!(Value::Char('c').as_bool(), None);
442            /// ```
443            pub fn as_bool(&self) -> Option<bool> {
444                match *self {
445                    Value::Bool(v) => Some(v),
446                    _ => None,
447                }
448            }
449
450            /// Return a `char` representation of `self`, if possible.
451            ///
452            /// # Examples
453            ///
454            /// ```
455            /// use valuable::Value;
456            ///
457            /// assert_eq!(Value::Char('c').as_char(), Some('c'));
458            /// assert_eq!(Value::Bool(true).as_char(), None);
459            /// ```
460            pub fn as_char(&self) -> Option<char> {
461                match *self {
462                    Value::Char(v) => Some(v),
463                    _ => None,
464                }
465            }
466
467            /// Return a `f32` representation of `self`, if possible.
468            ///
469            /// # Examples
470            ///
471            /// ```
472            /// use valuable::Value;
473            ///
474            /// assert_eq!(Value::F32(3.1415).as_f32(), Some(3.1415));
475            /// assert_eq!(Value::Bool(true).as_f32(), None);
476            /// ```
477            pub fn as_f32(&self) -> Option<f32> {
478                match *self {
479                    Value::F32(v) => Some(v),
480                    _ => None,
481                }
482            }
483
484            /// Return a `f64` representation of `self`, if possible.
485            ///
486            /// # Examples
487            ///
488            /// ```
489            /// use valuable::Value;
490            ///
491            /// assert_eq!(Value::F64(3.1415).as_f64(), Some(3.1415));
492            /// assert_eq!(Value::Bool(true).as_f64(), None);
493            /// ```
494            pub fn as_f64(&self) -> Option<f64> {
495                match *self {
496                    Value::F64(v) => Some(v),
497                    _ => None,
498                }
499            }
500
501            $(
502                $(#[$attrs])*
503                pub fn $as(&self) -> Option<$ty> {
504                    use Value::*;
505
506                    match *self {
507                        I8(v) => v.try_into().ok(),
508                        I16(v) => v.try_into().ok(),
509                        I32(v) => v.try_into().ok(),
510                        I64(v) => v.try_into().ok(),
511                        I128(v) => v.try_into().ok(),
512                        Isize(v) => v.try_into().ok(),
513                        U8(v) => v.try_into().ok(),
514                        U16(v) => v.try_into().ok(),
515                        U32(v) => v.try_into().ok(),
516                        U64(v) => v.try_into().ok(),
517                        U128(v) => v.try_into().ok(),
518                        Usize(v) => v.try_into().ok(),
519                        _ => None,
520                    }
521                }
522            )*
523
524            /// Return a `&str` representation of `self`, if possible.
525            ///
526            /// # Examples
527            ///
528            /// ```
529            /// use valuable::Value;
530            ///
531            /// assert_eq!(Value::String("hello").as_str(), Some("hello"));
532            /// assert_eq!(Value::Bool(true).as_str(), None);
533            /// ```
534            pub fn as_str(&self) -> Option<&str> {
535                match *self {
536                    Value::String(v) => Some(v),
537                    _ => None,
538                }
539            }
540
541            /// Return a `&Path` representation of `self`, if possible.
542            ///
543            /// # Examples
544            ///
545            /// ```
546            /// use valuable::Value;
547            /// use std::path::Path;
548            ///
549            /// let path = Path::new("a.txt");
550            ///
551            /// assert!(Value::Path(path).as_path().is_some());
552            /// assert!(Value::Bool(true).as_path().is_none());
553            /// ```
554            #[cfg(feature = "std")]
555            pub fn as_path(&self) -> Option<&std::path::Path> {
556                match *self {
557                    Value::Path(v) => Some(v),
558                    _ => None,
559                }
560            }
561
562            /// Return a `&dyn Error` representation of `self`, if possible.
563            ///
564            /// # Examples
565            ///
566            /// ```
567            /// use valuable::Value;
568            /// use std::io;
569            ///
570            /// let err: io::Error = io::ErrorKind::Other.into();
571            ///
572            /// assert!(Value::Error(&err).as_error().is_some());
573            /// assert!(Value::Bool(true).as_error().is_none());
574            /// ```
575            #[cfg(feature = "std")]
576            pub fn as_error(&self) -> Option<&(dyn std::error::Error + 'static)> {
577                match *self {
578                    Value::Error(v) => Some(v),
579                    _ => None,
580                }
581            }
582
583
584            /// Return a `&dyn Listable` representation of `self`, if possible.
585            ///
586            /// # Examples
587            ///
588            /// ```
589            /// use valuable::Value;
590            ///
591            /// let list = vec![1, 2, 3, 4];
592            ///
593            /// assert!(Value::Listable(&list).as_listable().is_some());
594            /// assert!(Value::Bool(true).as_listable().is_none());
595            /// ```
596            pub fn as_listable(&self) -> Option<&dyn Listable> {
597                match *self {
598                    Value::Listable(v) => Some(v),
599                    _ => None,
600                }
601            }
602
603            /// Return a `&dyn Mappable` representation of `self`, if possible.
604            ///
605            /// # Examples
606            ///
607            /// ```
608            /// use valuable::Value;
609            /// use std::collections::HashMap;
610            ///
611            /// let mut map = HashMap::new();
612            /// map.insert("foo", 123);
613            /// map.insert("bar", 456);
614            ///
615            /// assert!(Value::Mappable(&map).as_mappable().is_some());
616            /// assert!(Value::Bool(true).as_mappable().is_none());
617            /// ```
618            pub fn as_mappable(&self) -> Option<&dyn Mappable> {
619                match *self {
620                    Value::Mappable(v) => Some(v),
621                    _ => None,
622                }
623            }
624
625            /// Return a `&dyn Structable` representation of `self`, if possible.
626            ///
627            /// # Examples
628            ///
629            /// ```
630            /// use valuable::{Value, Valuable};
631            ///
632            /// #[derive(Valuable)]
633            /// struct Hello {
634            ///     message: &'static str,
635            /// }
636            ///
637            /// let hello = Hello { message: "Hello world" };
638            ///
639            /// assert!(Value::Structable(&hello).as_structable().is_some());
640            /// assert!(Value::Bool(true).as_structable().is_none());
641            /// ```
642            pub fn as_structable(&self) -> Option<&dyn Structable> {
643                match *self {
644                    Value::Structable(v) => Some(v),
645                    _ => None,
646                }
647            }
648
649            /// Return a `&dyn Enumerable` representation of `self`, if possible.
650            ///
651            /// # Examples
652            ///
653            /// ```
654            /// use valuable::{Value, Valuable};
655            ///
656            /// #[derive(Valuable)]
657            /// enum Greet {
658            ///     Hello,
659            ///     World,
660            /// }
661            ///
662            /// let greet = Greet::Hello;
663            ///
664            /// assert!(Value::Enumerable(&greet).as_enumerable().is_some());
665            /// assert!(Value::Bool(true).as_enumerable().is_none());
666            /// ```
667            pub fn as_enumerable(&self) -> Option<&dyn Enumerable> {
668                match *self {
669                    Value::Enumerable(v) => Some(v),
670                    _ => None,
671                }
672            }
673
674            /// Return a `&dyn Tuplable` representation of `self`, if possible.
675            ///
676            /// # Examples
677            ///
678            /// ```
679            /// use valuable::Value;
680            ///
681            /// let my_tuple = (123, 456);
682            ///
683            /// assert!(Value::Tuplable(&my_tuple).as_tuplable().is_some());
684            /// assert!(Value::Bool(true).as_tuplable().is_none());
685            /// ```
686            pub fn as_tuplable(&self) -> Option<&dyn Tuplable> {
687                match *self {
688                    Value::Tuplable(v) => Some(v),
689                    _ => None,
690                }
691            }
692        }
693    }
694}
695
696convert! {
697    /// Return a `i8` representation of `self`, if possible.
698    ///
699    /// # Examples
700    ///
701    /// ```
702    /// use valuable::Value;
703    ///
704    /// assert_eq!(Value::I8(42).as_i8(), Some(42));
705    /// assert_eq!(Value::I32(42).as_i8(), Some(42));
706    ///
707    /// assert_eq!(Value::I64(i64::MAX).as_i8(), None);
708    /// assert_eq!(Value::Bool(true).as_i8(), None);
709    /// ```
710    i8 => as_i8,
711
712    /// Return a `i16` representation of `self`, if possible.
713    ///
714    /// # Examples
715    ///
716    /// ```
717    /// use valuable::Value;
718    ///
719    /// assert_eq!(Value::I16(42).as_i16(), Some(42));
720    /// assert_eq!(Value::I32(42).as_i16(), Some(42));
721    ///
722    /// assert_eq!(Value::I64(i64::MAX).as_i16(), None);
723    /// assert_eq!(Value::Bool(true).as_i16(), None);
724    /// ```
725    i16 => as_i16,
726
727    /// Return a `i32` representation of `self`, if possible.
728    ///
729    /// # Examples
730    ///
731    /// ```
732    /// use valuable::Value;
733    ///
734    /// assert_eq!(Value::I32(42).as_i32(), Some(42));
735    /// assert_eq!(Value::I64(42).as_i32(), Some(42));
736    ///
737    /// assert_eq!(Value::I64(i64::MAX).as_i32(), None);
738    /// assert_eq!(Value::Bool(true).as_i32(), None);
739    /// ```
740    i32 => as_i32,
741
742    /// Return a `i64` representation of `self`, if possible.
743    ///
744    /// # Examples
745    ///
746    /// ```
747    /// use valuable::Value;
748    ///
749    /// assert_eq!(Value::I64(42).as_i64(), Some(42));
750    /// assert_eq!(Value::I128(42).as_i64(), Some(42));
751    ///
752    /// assert_eq!(Value::I128(i128::MAX).as_i64(), None);
753    /// assert_eq!(Value::Bool(true).as_i64(), None);
754    /// ```
755    i64 => as_i64,
756
757    /// Return a `i128` representation of `self`, if possible.
758    ///
759    /// # Examples
760    ///
761    /// ```
762    /// use valuable::Value;
763    ///
764    /// assert_eq!(Value::I128(42).as_i128(), Some(42));
765    /// assert_eq!(Value::U128(42).as_i128(), Some(42));
766    ///
767    /// assert_eq!(Value::U128(u128::MAX).as_i128(), None);
768    /// assert_eq!(Value::Bool(true).as_i128(), None);
769    /// ```
770    i128 => as_i128,
771
772    /// Return a `isize` representation of `self`, if possible.
773    ///
774    /// # Examples
775    ///
776    /// ```
777    /// use valuable::Value;
778    ///
779    /// assert_eq!(Value::Isize(42).as_isize(), Some(42));
780    /// assert_eq!(Value::Usize(42).as_isize(), Some(42));
781    ///
782    /// assert_eq!(Value::Usize(usize::MAX).as_isize(), None);
783    /// assert_eq!(Value::Bool(true).as_isize(), None);
784    /// ```
785    isize => as_isize,
786
787    /// Return a `u8` representation of `self`, if possible.
788    ///
789    /// # Examples
790    ///
791    /// ```
792    /// use valuable::Value;
793    ///
794    /// assert_eq!(Value::U8(42).as_u8(), Some(42));
795    /// assert_eq!(Value::U32(42).as_u8(), Some(42));
796    ///
797    /// assert_eq!(Value::U32(u32::MAX).as_u8(), None);
798    /// assert_eq!(Value::Bool(true).as_u8(), None);
799    /// ```
800    u8 => as_u8,
801
802    /// Return a `u16` representation of `self`, if possible.
803    ///
804    /// # Examples
805    ///
806    /// ```
807    /// use valuable::Value;
808    ///
809    /// assert_eq!(Value::U16(42).as_u16(), Some(42));
810    /// assert_eq!(Value::U32(42).as_u16(), Some(42));
811    ///
812    /// assert_eq!(Value::U32(u32::MAX).as_u16(), None);
813    /// assert_eq!(Value::Bool(true).as_u16(), None);
814    /// ```
815    u16 => as_u16,
816
817    /// Return a `u32` representation of `self`, if possible.
818    ///
819    /// # Examples
820    ///
821    /// ```
822    /// use valuable::Value;
823    ///
824    /// assert_eq!(Value::U32(42).as_u32(), Some(42));
825    /// assert_eq!(Value::U64(42).as_u32(), Some(42));
826    ///
827    /// assert_eq!(Value::U64(u64::MAX).as_u32(), None);
828    /// assert_eq!(Value::Bool(true).as_u32(), None);
829    /// ```
830    u32 => as_u32,
831
832    /// Return a `u64` representation of `self`, if possible.
833    ///
834    /// # Examples
835    ///
836    /// ```
837    /// use valuable::Value;
838    ///
839    /// assert_eq!(Value::U64(42).as_u64(), Some(42));
840    /// assert_eq!(Value::U128(42).as_u64(), Some(42));
841    ///
842    /// assert_eq!(Value::U128(u128::MAX).as_u64(), None);
843    /// assert_eq!(Value::Bool(true).as_u64(), None);
844    /// ```
845    u64 => as_u64,
846
847    /// Return a `u128` representation of `self`, if possible.
848    ///
849    /// # Examples
850    ///
851    /// ```
852    /// use valuable::Value;
853    ///
854    /// assert_eq!(Value::U128(42).as_u128(), Some(42));
855    /// assert_eq!(Value::I32(42).as_u128(), Some(42));
856    ///
857    /// assert_eq!(Value::I32(-5).as_u128(), None);
858    /// assert_eq!(Value::Bool(true).as_u128(), None);
859    /// ```
860    u128 => as_u128,
861
862    /// Return a `usize` representation of `self`, if possible.
863    ///
864    /// # Examples
865    ///
866    /// ```
867    /// use valuable::Value;
868    ///
869    /// assert_eq!(Value::Usize(42).as_usize(), Some(42));
870    /// assert_eq!(Value::I8(42).as_usize(), Some(42));
871    ///
872    /// assert_eq!(Value::I8(-5).as_usize(), None);
873    /// assert_eq!(Value::Bool(true).as_usize(), None);
874    /// ```
875    usize => as_usize,
876}