1use 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}