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}