1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use DeriveInput;
/// A trait for grouping together different new-type variants that dereference to
/// the same type, reducing boilerplate code.
///
/// Implements [`std::ops::Deref`] and [`std::ops::DerefMut`] for enums composed
/// of solely of new-type-style variants.
///
/// The variants must hold "compatible" types, which means they must be deref-able
/// to the same type (e.g. String and &str, Box<T> and T).
///
/// The macro accompanies the macro-attribute `enum_deref_target` to define what
/// type the enum should deref to.
///
/// ```
/// use enutil::EnumDeref;
/// use enutil_macros::EnumDeref;
///
/// #[derive(EnumDeref)]
/// #[enum_deref_target([u32])]
/// enum Collection {
/// Fixed([u32; 2]),
/// Dynamic(Vec<u32>),
/// }
///
/// let mut f = Collection::Fixed([5, 6]);
/// assert_eq!(&*f, &[5, 6]);
///
/// f[0] = 10;
/// assert_eq!(&*f, &[10, 6]);
///
/// let mut d = Collection::Dynamic(Vec::from([9]));
/// assert_eq!(&*d, &[9]);
///
/// d[0] = 1;
/// assert_eq!(&*d, &[1]);
/// ```
///
/// You may also deref trait object references using `dyn Trait` for something
/// resembling a `Box<T>`, but with all the benefits of having an enum, such as
/// compile-time known variants.
///
/// ```
/// use enutil::EnumDeref;
/// use enutil_macros::EnumDeref;
///
/// #[derive(EnumDeref)]
/// #[enum_deref_target(dyn core::fmt::Display)]
/// enum Column {
/// Text(String),
/// Number(i32),
/// Float(f32),
/// }
///
/// let t = Column::Text("Hi!".to_string());
/// assert_eq!((*t).to_string(), "Hi!");
///
/// let n = Column::Number(4);
/// assert_eq!((*n).to_string(), "4");
///
/// let f = Column::Float(5.125);
/// assert_eq!((*f).to_string(), "5.125");
///
/// fn prints_something(smth: &dyn core::fmt::Display) {
/// println!("{smth}");
/// }
///
/// prints_something(&*t);
/// prints_something(&*n);
/// prints_something(&*f);
/// ```