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