artichoke_backend/convert/
nilable.rs1use crate::Artichoke;
6use crate::core::{Convert, TryConvert, TryConvertMut, Value as _};
7use crate::error::Error;
8use crate::value::Value;
9
10impl Convert<Option<Value>, Value> for Artichoke {
11 fn convert(&self, value: Option<Value>) -> Value {
12 Value::from(value)
13 }
14}
15
16impl Convert<Option<i64>, Value> for Artichoke {
17 fn convert(&self, value: Option<i64>) -> Value {
18 let Some(value) = value else {
19 return Value::nil();
20 };
21 self.convert(value)
22 }
23}
24
25impl TryConvert<Option<usize>, Value> for Artichoke {
26 type Error = Error;
27
28 fn try_convert(&self, value: Option<usize>) -> Result<Value, Self::Error> {
29 let Some(value) = value else {
30 return Ok(Value::nil());
31 };
32 self.try_convert(value)
33 }
34}
35
36impl TryConvertMut<Option<Vec<u8>>, Value> for Artichoke {
37 type Error = Error;
38
39 fn try_convert_mut(&mut self, value: Option<Vec<u8>>) -> Result<Value, Self::Error> {
40 self.try_convert_mut(value.as_deref())
41 }
42}
43
44impl TryConvertMut<Option<&[u8]>, Value> for Artichoke {
45 type Error = Error;
46
47 fn try_convert_mut(&mut self, value: Option<&[u8]>) -> Result<Value, Self::Error> {
48 let Some(value) = value else {
49 return Ok(Value::nil());
50 };
51 self.try_convert_mut(value)
52 }
53}
54
55impl TryConvertMut<Option<String>, Value> for Artichoke {
56 type Error = Error;
57
58 fn try_convert_mut(&mut self, value: Option<String>) -> Result<Value, Self::Error> {
59 self.try_convert_mut(value.as_deref())
60 }
61}
62
63impl TryConvertMut<Option<&str>, Value> for Artichoke {
64 type Error = Error;
65
66 fn try_convert_mut(&mut self, value: Option<&str>) -> Result<Value, Self::Error> {
67 let Some(value) = value else {
68 return Ok(Value::nil());
69 };
70 self.try_convert_mut(value)
71 }
72}
73
74impl Convert<Value, Option<Value>> for Artichoke {
75 fn convert(&self, value: Value) -> Option<Value> {
76 if value.is_nil() { None } else { Some(value) }
77 }
78}
79
80impl TryConvertMut<Value, Option<Vec<u8>>> for Artichoke {
81 type Error = Error;
82
83 fn try_convert_mut(&mut self, value: Value) -> Result<Option<Vec<u8>>, Self::Error> {
84 if value.is_nil() {
85 return Ok(None);
86 }
87 self.try_convert_mut(value).map(Some)
88 }
89}
90
91impl<'a> TryConvertMut<Value, Option<&'a [u8]>> for Artichoke {
92 type Error = Error;
93
94 fn try_convert_mut(&mut self, value: Value) -> Result<Option<&'a [u8]>, Self::Error> {
95 if value.is_nil() {
96 return Ok(None);
97 }
98 self.try_convert_mut(value).map(Some)
99 }
100}
101
102impl TryConvertMut<Value, Option<String>> for Artichoke {
103 type Error = Error;
104
105 fn try_convert_mut(&mut self, value: Value) -> Result<Option<String>, Self::Error> {
106 if value.is_nil() {
107 return Ok(None);
108 }
109 self.try_convert_mut(value).map(Some)
110 }
111}
112
113impl<'a> TryConvertMut<Value, Option<&'a str>> for Artichoke {
114 type Error = Error;
115
116 fn try_convert_mut(&mut self, value: Value) -> Result<Option<&'a str>, Self::Error> {
117 if value.is_nil() {
118 return Ok(None);
119 }
120 self.try_convert_mut(value).map(Some)
121 }
122}
123
124impl TryConvert<Value, Option<i64>> for Artichoke {
125 type Error = Error;
126
127 fn try_convert(&self, value: Value) -> Result<Option<i64>, Self::Error> {
128 if value.is_nil() {
129 return Ok(None);
130 }
131 self.try_convert(value).map(Some)
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use crate::core::{Convert, TryConvert, TryConvertMut};
138 use crate::test::prelude::*;
139 use crate::value::Value;
140
141 #[test]
142 fn convert_option_value_some_returns_the_inner_value() {
143 let interp = interpreter();
144 let inner = interp.convert(42_i64);
145 let value = interp.convert(Some(inner));
146 assert!(!value.is_nil());
148 let num = value.try_convert_into::<i64>(&interp).unwrap();
150 assert_eq!(num, 42);
151 }
152
153 #[test]
154 fn convert_option_value_none_returns_nil() {
155 let interp = interpreter();
156 let value = interp.convert(None::<Value>);
157 assert!(value.is_nil());
158 }
159
160 #[test]
161 fn convert_value_to_option_value_non_nil_returns_some() {
162 let interp = interpreter();
163 let value = interp.convert(789_i64);
164 let opt: Option<Value> = interp.convert(value);
165 assert!(opt.is_some());
166 let num = opt.unwrap().try_convert_into::<i64>(&interp).unwrap();
167 assert_eq!(num, 789);
168 }
169
170 #[test]
171 fn convert_value_to_option_value_nil_returns_none() {
172 let interp = interpreter();
173 let nil_value = Value::nil();
174 let opt: Option<Value> = interp.convert(nil_value);
175 assert!(opt.is_none());
176 }
177
178 #[test]
181 fn convert_option_i64_some_converts_to_fixnum() {
182 let interp = interpreter();
183 let value = interp.convert(Some(123_i64));
184 let num = value.try_convert_into::<i64>(&interp).unwrap();
185 assert_eq!(num, 123);
186 }
187
188 #[test]
189 fn convert_option_i64_none_converts_to_nil() {
190 let interp = interpreter();
191 let value = interp.convert(None::<i64>);
192 assert!(value.is_nil());
193 }
194
195 #[test]
198 fn try_convert_option_usize_some_converts_to_fixnum() {
199 let interp = interpreter();
200 let value = interp.try_convert(Some(456_usize)).unwrap();
201 let num: usize = value.try_convert_into(&interp).unwrap();
202 assert_eq!(num, 456);
203 }
204
205 #[test]
206 fn try_convert_option_usize_none_converts_to_nil() {
207 let interp = interpreter();
208 let value = interp.try_convert(None::<usize>).unwrap();
209 assert!(value.is_nil());
210 }
211
212 #[test]
215 fn try_convert_mut_option_vec_u8_some_converts_to_string() {
216 let mut interp = interpreter();
217 let input = b"hello".to_vec();
218 let value = interp.try_convert_mut(Some(input.clone())).unwrap();
219 let result = value.try_convert_into_mut::<Option<String>>(&mut interp).unwrap();
221 assert_eq!(result, Some(String::from("hello")));
222 }
223
224 #[test]
225 fn try_convert_mut_option_vec_u8_none_converts_to_nil() {
226 let mut interp = interpreter();
227 let value = interp.try_convert_mut(None::<Vec<u8>>).unwrap();
228 assert!(value.is_nil());
229 }
230
231 #[test]
234 fn try_convert_mut_option_slice_u8_some_converts_to_string() {
235 let mut interp = interpreter();
236 let input: &[u8] = b"world";
237 let value = interp.try_convert_mut(Some(input)).unwrap();
238 let result = value.try_convert_into_mut::<Option<String>>(&mut interp).unwrap();
239 assert_eq!(result, Some(String::from("world")));
240 }
241
242 #[test]
243 fn try_convert_mut_option_slice_u8_none_converts_to_nil() {
244 let mut interp = interpreter();
245 let value = interp.try_convert_mut(None::<&[u8]>).unwrap();
246 assert!(value.is_nil());
247 }
248
249 #[test]
250 fn try_convert_mut_option_string_some_converts_to_string() {
251 let mut interp = interpreter();
252 let input = String::from("artichoke");
253 let value = interp.try_convert_mut(Some(input.clone())).unwrap();
254 let result = value.try_convert_into_mut::<Option<String>>(&mut interp).unwrap();
255 assert_eq!(result, Some(input));
256 }
257
258 #[test]
259 fn try_convert_mut_option_string_none_converts_to_nil() {
260 let mut interp = interpreter();
261 let value = interp.try_convert_mut(None::<String>).unwrap();
262 assert!(value.is_nil());
263 }
264
265 #[test]
268 fn try_convert_mut_option_str_some_converts_to_string() {
269 let mut interp = interpreter();
270 let input = "convert me";
271 let value = interp.try_convert_mut(Some(input)).unwrap();
272 let result = value.try_convert_into_mut::<Option<String>>(&mut interp).unwrap();
273 assert_eq!(result, Some(input.to_owned()));
274 }
275
276 #[test]
277 fn try_convert_mut_option_str_none_converts_to_nil() {
278 let mut interp = interpreter();
279 let value = interp.try_convert_mut(None::<&str>).unwrap();
280 assert!(value.is_nil());
281 }
282
283 #[test]
286 fn try_convert_mut_value_to_option_vec_u8_non_nil_returns_some() {
287 let mut interp = interpreter();
288 let value = interp.try_convert_mut("hello world").unwrap();
289 let result = value.try_convert_into_mut::<Option<Vec<u8>>>(&mut interp).unwrap();
290 let s = String::from_utf8(result.unwrap()).unwrap();
291 assert_eq!(s, "hello world");
292 }
293
294 #[test]
295 fn try_convert_mut_value_to_option_vec_u8_nil_returns_none() {
296 let mut interp = interpreter();
297 let value = Value::nil();
298 let result = value.try_convert_into_mut::<Option<Vec<u8>>>(&mut interp).unwrap();
299 assert!(result.is_none());
300 }
301
302 #[test]
305 fn try_convert_mut_value_to_option_slice_u8_non_nil_returns_some() {
306 let mut interp = interpreter();
307 let value = interp.try_convert_mut("slice-test").unwrap();
308 let result = value.try_convert_into_mut::<Option<&[u8]>>(&mut interp).unwrap();
309 let s = String::from_utf8(result.unwrap().to_vec()).unwrap();
310 assert_eq!(s, "slice-test");
311 }
312
313 #[test]
314 fn try_convert_mut_value_to_option_slice_u8_nil_returns_none() {
315 let mut interp = interpreter();
316 let value = Value::nil();
317 let result = value.try_convert_into_mut::<Option<&[u8]>>(&mut interp).unwrap();
318 assert!(result.is_none());
319 }
320
321 #[test]
324 fn try_convert_mut_value_to_option_string_non_nil_returns_some() {
325 let mut interp = interpreter();
326 let value = interp.try_convert_mut("string-test").unwrap();
327 let result = value.try_convert_into_mut::<Option<String>>(&mut interp).unwrap();
328 assert_eq!(result, Some(String::from("string-test")));
329 }
330
331 #[test]
332 fn try_convert_mut_value_to_option_string_nil_returns_none() {
333 let mut interp = interpreter();
334 let value = Value::nil();
335 let result = value.try_convert_into_mut::<Option<String>>(&mut interp).unwrap();
336 assert!(result.is_none());
337 }
338
339 #[test]
340 fn try_convert_mut_value_to_option_str_non_nil_returns_some() {
341 let mut interp = interpreter();
342 let value = interp.try_convert_mut("str-test").unwrap();
343 let result = value.try_convert_into_mut::<Option<&str>>(&mut interp).unwrap();
344 assert_eq!(result, Some("str-test"));
345 }
346
347 #[test]
348 fn try_convert_mut_value_to_option_str_nil_returns_none() {
349 let mut interp = interpreter();
350 let value = Value::nil();
351 let result = value.try_convert_into_mut::<Option<&str>>(&mut interp).unwrap();
352 assert!(result.is_none());
353 }
354
355 #[test]
356 fn try_convert_value_to_option_i64_non_nil_returns_some() {
357 let interp = interpreter();
358 let value = interp.convert(555i64);
359 let result = value.try_convert_into::<Option<i64>>(&interp).unwrap();
360 assert_eq!(result, Some(555));
361 }
362
363 #[test]
364 fn try_convert_value_to_option_i64_nil_returns_none() {
365 let interp = interpreter();
366 let value = Value::nil();
367 let result = value.try_convert_into::<Option<i64>>(&interp).unwrap();
368 assert!(result.is_none());
369 }
370}