value_bag/
impls.rs

1//! Converting standard types into `ValueBag`s.
2
3use super::{Error, ValueBag};
4
5macro_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
44impl<'v> From<()> for ValueBag<'v> {
45    #[inline]
46    fn from(_: ()) -> Self {
47        ValueBag::empty()
48    }
49}
50
51impl<'a, 'v> From<&'a ()> for ValueBag<'v> {
52    #[inline]
53    fn from(_: &'a ()) -> Self {
54        ValueBag::empty()
55    }
56}
57
58convert_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
74impl<'v> From<f32> for ValueBag<'v> {
75    #[inline]
76    fn from(v: f32) -> Self {
77        ValueBag::from_f32(v)
78    }
79}
80
81impl<'v> From<Option<f32>> for ValueBag<'v> {
82    #[inline]
83    fn from(v: Option<f32>) -> Self {
84        ValueBag::from_option(v)
85    }
86}
87
88impl<'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")]
96impl<'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"))]
104impl<'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")]
112impl<'v> From<u128> for ValueBag<'v> {
113    #[inline]
114    fn from(v: u128) -> Self {
115        ValueBag::from_u128(v)
116    }
117}
118
119impl<'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")]
129impl<'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"))]
137impl<'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")]
145impl<'v> From<i128> for ValueBag<'v> {
146    #[inline]
147    fn from(v: i128) -> Self {
148        ValueBag::from_i128(v)
149    }
150}
151
152impl<'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
161impl<'v> From<&'v str> for ValueBag<'v> {
162    #[inline]
163    fn from(v: &'v str) -> Self {
164        ValueBag::from_str(v)
165    }
166}
167
168impl<'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
175impl<'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
185impl<'v, 'u> From<&'v &'u str> for ValueBag<'v>
186where
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")]
196mod 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")]
237mod 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)]
251mod 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}