1 | use std::fmt; |
2 | |
3 | use syn::Lit; |
4 | |
5 | use crate::ast::NestedMeta; |
6 | use crate::{FromMeta, Result}; |
7 | |
8 | use self::Override::*; |
9 | |
10 | /// A value which can inherit a default value or have an explicit value specified. |
11 | /// |
12 | /// # Usage |
13 | /// This type is meant for attributes like `default` in `darling`, which can take the following forms: |
14 | /// |
15 | /// * `#[darling(default)]` |
16 | /// * `#[darling(default="path::to::fn")]` |
17 | /// |
18 | /// In a struct collecting input for this attribute, that would be written as: |
19 | /// |
20 | /// ```rust,ignore |
21 | /// use darling::{util::Override, FromField}; |
22 | /// #[derive(FromField)] |
23 | /// #[darling(attributes(darling))] |
24 | /// pub struct Options { |
25 | /// default: Option<Override<syn::Path>>, |
26 | /// } |
27 | /// |
28 | /// impl Options { |
29 | /// fn hydrate(self) -> Option<syn::Path> { |
30 | /// self.default.map(|ov| ov.unwrap_or(syn::parse_path("::Default::default" ).unwrap())) |
31 | /// } |
32 | /// } |
33 | /// ``` |
34 | /// |
35 | /// The `word` format (with no associated value), would produce `Override::Inherit`, while a list |
36 | /// or value format would produce `Override::Explicit`. |
37 | #[derive (Debug, Clone, PartialEq, Eq)] |
38 | pub enum Override<T> { |
39 | /// Inherit the eventual value from an external source. |
40 | Inherit, |
41 | |
42 | /// Explicitly set the value. |
43 | Explicit(T), |
44 | } |
45 | |
46 | impl<T> Override<T> { |
47 | /// Converts from `Override<T>` to `Override<&T>`. |
48 | /// |
49 | /// Produces a new `Override`, containing a reference into the original, leaving the original in place. |
50 | pub fn as_ref(&self) -> Override<&T> { |
51 | match *self { |
52 | Inherit => Inherit, |
53 | Explicit(ref val) => Explicit(val), |
54 | } |
55 | } |
56 | |
57 | /// Converts from `Override<T>` to `Override<&mut T>`. |
58 | /// |
59 | /// Produces a new `Override`, containing a mutable reference into the original. |
60 | pub fn as_mut(&mut self) -> Override<&mut T> { |
61 | match *self { |
62 | Inherit => Inherit, |
63 | Explicit(ref mut val) => Explicit(val), |
64 | } |
65 | } |
66 | |
67 | /// Returns `true` if the override is an `Explicit` value. |
68 | pub fn is_explicit(&self) -> bool { |
69 | match *self { |
70 | Inherit => false, |
71 | Explicit(_) => true, |
72 | } |
73 | } |
74 | |
75 | /// Converts from `Override<T>` to `Option<T>`. |
76 | pub fn explicit(self) -> Option<T> { |
77 | match self { |
78 | Inherit => None, |
79 | Explicit(val) => Some(val), |
80 | } |
81 | } |
82 | |
83 | /// Unwraps an override, yielding the content of an `Explicit`. Otherwise, it returns `optb`. |
84 | pub fn unwrap_or(self, optb: T) -> T { |
85 | match self { |
86 | Inherit => optb, |
87 | Explicit(val) => val, |
88 | } |
89 | } |
90 | |
91 | /// Unwraps an override, yielding the content of an `Explicit`. Otherwise, it calls `op`. |
92 | pub fn unwrap_or_else<F>(self, op: F) -> T |
93 | where |
94 | F: FnOnce() -> T, |
95 | { |
96 | match self { |
97 | Inherit => op(), |
98 | Explicit(val) => val, |
99 | } |
100 | } |
101 | } |
102 | |
103 | impl<T: Default> Override<T> { |
104 | /// Returns the contained value or the default value of `T`. |
105 | pub fn unwrap_or_default(self) -> T { |
106 | self.unwrap_or_else(op:Default::default) |
107 | } |
108 | } |
109 | |
110 | impl<T> Default for Override<T> { |
111 | fn default() -> Self { |
112 | Inherit |
113 | } |
114 | } |
115 | |
116 | impl<T> From<Option<T>> for Override<T> { |
117 | fn from(v: Option<T>) -> Self { |
118 | match v { |
119 | None => Inherit, |
120 | Some(val: T) => Explicit(val), |
121 | } |
122 | } |
123 | } |
124 | |
125 | impl<T: fmt::Display> fmt::Display for Override<T> { |
126 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
127 | match *self { |
128 | Inherit => write!(f, "Inherit" ), |
129 | Explicit(ref val: &T) => write!(f, "Explicit ` {}`" , val), |
130 | } |
131 | } |
132 | } |
133 | |
134 | /// Parses a `Meta`. A bare word will produce `Override::Inherit`, while |
135 | /// any value will be forwarded to `T::from_meta`. |
136 | impl<T: FromMeta> FromMeta for Override<T> { |
137 | fn from_word() -> Result<Self> { |
138 | Ok(Inherit) |
139 | } |
140 | |
141 | fn from_list(items: &[NestedMeta]) -> Result<Self> { |
142 | Ok(Explicit(FromMeta::from_list(items)?)) |
143 | } |
144 | |
145 | fn from_value(lit: &Lit) -> Result<Self> { |
146 | Ok(Explicit(FromMeta::from_value(lit)?)) |
147 | } |
148 | } |
149 | |