1 | //! Converting standard types into `ValueBag`s. |
2 | |
3 | use super::{Error, ValueBag}; |
4 | |
5 | macro_rules! convert_primitive { |
6 | ($($t:ty: $from:ident, $to:ident,)*) => { |
7 | $( |
8 | impl<'v> From<$t> for ValueBag<'v> { |
9 | #[inline] |
10 | fn from(v: $t) -> Self { |
11 | ValueBag::$from(v) |
12 | } |
13 | } |
14 | |
15 | impl<'a, 'v> From<&'a $t> for ValueBag<'v> { |
16 | #[inline] |
17 | fn from(v: &'a $t) -> Self { |
18 | ValueBag::$from(*v) |
19 | } |
20 | } |
21 | |
22 | impl<'v> From<Option<$t>> for ValueBag<'v> { |
23 | #[inline] |
24 | fn from(v: Option<$t>) -> Self { |
25 | ValueBag::from_option(v) |
26 | } |
27 | } |
28 | |
29 | impl<'v> TryFrom<ValueBag<'v>> for $t { |
30 | type Error = Error; |
31 | |
32 | #[inline] |
33 | fn try_from(v: ValueBag<'v>) -> Result<Self, Error> { |
34 | v.$to() |
35 | .ok_or_else(|| Error::msg("conversion failed" ))? |
36 | .try_into() |
37 | .map_err(|_| Error::msg("conversion failed" )) |
38 | } |
39 | } |
40 | )* |
41 | }; |
42 | } |
43 | |
44 | impl<'v> From<()> for ValueBag<'v> { |
45 | #[inline ] |
46 | fn from(_: ()) -> Self { |
47 | ValueBag::empty() |
48 | } |
49 | } |
50 | |
51 | impl<'a, 'v> From<&'a ()> for ValueBag<'v> { |
52 | #[inline ] |
53 | fn from(_: &'a ()) -> Self { |
54 | ValueBag::empty() |
55 | } |
56 | } |
57 | |
58 | convert_primitive!( |
59 | u8: from_u8, to_u64, |
60 | u16: from_u16, to_u64, |
61 | u32: from_u32, to_u64, |
62 | u64: from_u64, to_u64, |
63 | usize: from_usize, to_u64, |
64 | i8: from_i8, to_i64, |
65 | i16: from_i16, to_i64, |
66 | i32: from_i32, to_i64, |
67 | i64: from_i64, to_i64, |
68 | isize: from_isize, to_i64, |
69 | f64: from_f64, to_f64, |
70 | bool: from_bool, to_bool, |
71 | char: from_char, to_char, |
72 | ); |
73 | |
74 | impl<'v> From<f32> for ValueBag<'v> { |
75 | #[inline ] |
76 | fn from(v: f32) -> Self { |
77 | ValueBag::from_f32(v) |
78 | } |
79 | } |
80 | |
81 | impl<'v> From<Option<f32>> for ValueBag<'v> { |
82 | #[inline ] |
83 | fn from(v: Option<f32>) -> Self { |
84 | ValueBag::from_option(v) |
85 | } |
86 | } |
87 | |
88 | impl<'a, 'v> From<&'a f32> for ValueBag<'v> { |
89 | #[inline ] |
90 | fn from(v: &'a f32) -> Self { |
91 | ValueBag::from_f32(*v) |
92 | } |
93 | } |
94 | |
95 | #[cfg (feature = "inline-i128" )] |
96 | impl<'a, 'v> From<&'a u128> for ValueBag<'v> { |
97 | #[inline ] |
98 | fn from(v: &'a u128) -> Self { |
99 | ValueBag::from_u128(*v) |
100 | } |
101 | } |
102 | |
103 | #[cfg (not(feature = "inline-i128" ))] |
104 | impl<'v> From<&'v u128> for ValueBag<'v> { |
105 | #[inline ] |
106 | fn from(v: &'v u128) -> Self { |
107 | ValueBag::from_u128_ref(v) |
108 | } |
109 | } |
110 | |
111 | #[cfg (feature = "inline-i128" )] |
112 | impl<'v> From<u128> for ValueBag<'v> { |
113 | #[inline ] |
114 | fn from(v: u128) -> Self { |
115 | ValueBag::from_u128(v) |
116 | } |
117 | } |
118 | |
119 | impl<'v> TryFrom<ValueBag<'v>> for u128 { |
120 | type Error = Error; |
121 | |
122 | #[inline ] |
123 | fn try_from(v: ValueBag<'v>) -> Result<Self, Error> { |
124 | v.to_u128().ok_or_else(|| Error::msg("conversion failed" )) |
125 | } |
126 | } |
127 | |
128 | #[cfg (feature = "inline-i128" )] |
129 | impl<'a, 'v> From<&'a i128> for ValueBag<'v> { |
130 | #[inline ] |
131 | fn from(v: &'a i128) -> Self { |
132 | ValueBag::from_i128(*v) |
133 | } |
134 | } |
135 | |
136 | #[cfg (not(feature = "inline-i128" ))] |
137 | impl<'v> From<&'v i128> for ValueBag<'v> { |
138 | #[inline ] |
139 | fn from(v: &'v i128) -> Self { |
140 | ValueBag::from_i128_ref(v) |
141 | } |
142 | } |
143 | |
144 | #[cfg (feature = "inline-i128" )] |
145 | impl<'v> From<i128> for ValueBag<'v> { |
146 | #[inline ] |
147 | fn from(v: i128) -> Self { |
148 | ValueBag::from_i128(v) |
149 | } |
150 | } |
151 | |
152 | impl<'v> TryFrom<ValueBag<'v>> for i128 { |
153 | type Error = Error; |
154 | |
155 | #[inline ] |
156 | fn try_from(v: ValueBag<'v>) -> Result<Self, Error> { |
157 | v.to_i128().ok_or_else(|| Error::msg("conversion failed" )) |
158 | } |
159 | } |
160 | |
161 | impl<'v> From<&'v str> for ValueBag<'v> { |
162 | #[inline ] |
163 | fn from(v: &'v str) -> Self { |
164 | ValueBag::from_str(v) |
165 | } |
166 | } |
167 | |
168 | impl<'v> From<Option<&'v str>> for ValueBag<'v> { |
169 | #[inline ] |
170 | fn from(v: Option<&'v str>) -> Self { |
171 | ValueBag::from_option(v) |
172 | } |
173 | } |
174 | |
175 | impl<'v> TryFrom<ValueBag<'v>> for &'v str { |
176 | type Error = Error; |
177 | |
178 | #[inline ] |
179 | fn try_from(v: ValueBag<'v>) -> Result<Self, Error> { |
180 | v.to_borrowed_str() |
181 | .ok_or_else(|| Error::msg("conversion failed" )) |
182 | } |
183 | } |
184 | |
185 | impl<'v, 'u> From<&'v &'u str> for ValueBag<'v> |
186 | where |
187 | 'u: 'v, |
188 | { |
189 | #[inline ] |
190 | fn from(v: &'v &'u str) -> Self { |
191 | ValueBag::from_str(v) |
192 | } |
193 | } |
194 | |
195 | #[cfg (feature = "alloc" )] |
196 | mod alloc_support { |
197 | use super::*; |
198 | |
199 | use crate::std::{borrow::Cow, string::String}; |
200 | |
201 | impl<'v> From<&'v String> for ValueBag<'v> { |
202 | #[inline ] |
203 | fn from(v: &'v String) -> Self { |
204 | ValueBag::from_str(v) |
205 | } |
206 | } |
207 | |
208 | impl<'v> TryFrom<ValueBag<'v>> for String { |
209 | type Error = Error; |
210 | |
211 | #[inline ] |
212 | fn try_from(v: ValueBag<'v>) -> Result<Self, Error> { |
213 | Ok(v.to_str() |
214 | .ok_or_else(|| Error::msg("conversion failed" ))? |
215 | .into_owned()) |
216 | } |
217 | } |
218 | |
219 | impl<'v> From<&'v Cow<'v, str>> for ValueBag<'v> { |
220 | #[inline ] |
221 | fn from(v: &'v Cow<'v, str>) -> Self { |
222 | ValueBag::from_str(v) |
223 | } |
224 | } |
225 | |
226 | impl<'v> TryFrom<ValueBag<'v>> for Cow<'v, str> { |
227 | type Error = Error; |
228 | |
229 | #[inline ] |
230 | fn try_from(v: ValueBag<'v>) -> Result<Self, Error> { |
231 | v.to_str().ok_or_else(|| Error::msg("conversion failed" )) |
232 | } |
233 | } |
234 | } |
235 | |
236 | #[cfg (feature = "owned" )] |
237 | mod owned_support { |
238 | use super::*; |
239 | |
240 | use crate::OwnedValueBag; |
241 | |
242 | impl<'v> From<&'v OwnedValueBag> for ValueBag<'v> { |
243 | #[inline ] |
244 | fn from(v: &'v OwnedValueBag) -> ValueBag<'v> { |
245 | v.by_ref() |
246 | } |
247 | } |
248 | } |
249 | |
250 | #[cfg (test)] |
251 | mod tests { |
252 | #[cfg (target_arch = "wasm32" )] |
253 | use wasm_bindgen_test::*; |
254 | |
255 | use crate::{ |
256 | std::{borrow::ToOwned, string::ToString}, |
257 | test::{IntoValueBag, TestToken}, |
258 | }; |
259 | |
260 | #[test ] |
261 | #[cfg_attr (target_arch = "wasm32" , wasm_bindgen_test)] |
262 | fn test_into_display() { |
263 | assert_eq!(42u64.into_value_bag().by_ref().to_string(), "42" ); |
264 | assert_eq!(42i64.into_value_bag().by_ref().to_string(), "42" ); |
265 | assert_eq!(42.01f64.into_value_bag().by_ref().to_string(), "42.01" ); |
266 | assert_eq!(true.into_value_bag().by_ref().to_string(), "true" ); |
267 | assert_eq!('a' .into_value_bag().by_ref().to_string(), "a" ); |
268 | assert_eq!( |
269 | "a loong string" .into_value_bag().by_ref().to_string(), |
270 | "a loong string" |
271 | ); |
272 | assert_eq!(().into_value_bag().by_ref().to_string(), "None" ); |
273 | } |
274 | |
275 | #[test ] |
276 | #[cfg_attr (target_arch = "wasm32" , wasm_bindgen_test)] |
277 | fn test_into_structured() { |
278 | assert_eq!( |
279 | 42u64.into_value_bag().by_ref().to_test_token(), |
280 | TestToken::U64(42) |
281 | ); |
282 | assert_eq!( |
283 | 42i64.into_value_bag().by_ref().to_test_token(), |
284 | TestToken::I64(42) |
285 | ); |
286 | assert_eq!( |
287 | 42.01f64.into_value_bag().by_ref().to_test_token(), |
288 | TestToken::F64(42.01) |
289 | ); |
290 | assert_eq!( |
291 | true.into_value_bag().by_ref().to_test_token(), |
292 | TestToken::Bool(true) |
293 | ); |
294 | assert_eq!( |
295 | 'a' .into_value_bag().by_ref().to_test_token(), |
296 | TestToken::Char('a' ) |
297 | ); |
298 | assert_eq!( |
299 | "a loong string" .into_value_bag().by_ref().to_test_token(), |
300 | TestToken::Str("a loong string" .to_owned()) |
301 | ); |
302 | assert_eq!( |
303 | ().into_value_bag().by_ref().to_test_token(), |
304 | TestToken::None |
305 | ); |
306 | |
307 | #[cfg (feature = "inline-i128" )] |
308 | { |
309 | assert_eq!( |
310 | 42u128.into_value_bag().by_ref().to_test_token(), |
311 | TestToken::U128(42) |
312 | ); |
313 | assert_eq!( |
314 | 42i128.into_value_bag().by_ref().to_test_token(), |
315 | TestToken::I128(42) |
316 | ); |
317 | } |
318 | } |
319 | } |
320 | |