1use crate::{Any, AnyObj, Mut, RawMut, RawRef, Ref, Shared, StaticString, Value, VmError};
2use std::sync::Arc;
3
4pub trait FromValue: 'static + Sized {
6 fn from_value(value: Value) -> Result<Self, VmError>;
8}
9
10pub trait UnsafeFromValue: Sized {
17 type Output: 'static;
19
20 type Guard: 'static;
25
26 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError>;
36
37 unsafe fn unsafe_coerce(output: Self::Output) -> Self;
47}
48
49impl<T> FromValue for T
50where
51 T: Any,
52{
53 fn from_value(value: Value) -> Result<Self, VmError> {
54 Ok(value.into_any()?.take_downcast()?)
55 }
56}
57
58impl<T> FromValue for Mut<T>
59where
60 T: Any,
61{
62 fn from_value(value: Value) -> Result<Self, VmError> {
63 Ok(value.into_any()?.downcast_into_mut()?)
64 }
65}
66
67impl<T> FromValue for Ref<T>
68where
69 T: Any,
70{
71 fn from_value(value: Value) -> Result<Self, VmError> {
72 Ok(value.into_any()?.downcast_into_ref()?)
73 }
74}
75
76impl FromValue for Shared<AnyObj> {
77 fn from_value(value: Value) -> Result<Self, VmError> {
78 Ok(value.into_any()?)
79 }
80}
81
82impl<T> UnsafeFromValue for T
83where
84 T: FromValue,
85{
86 type Output = T;
87 type Guard = ();
88
89 fn from_value(value: Value) -> Result<(Self, Self::Guard), VmError> {
90 Ok((T::from_value(value)?, ()))
91 }
92
93 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
94 output
95 }
96}
97
98impl FromValue for Value {
99 fn from_value(value: Value) -> Result<Self, VmError> {
100 Ok(value)
101 }
102}
103
104impl<T> FromValue for Option<T>
107where
108 T: FromValue,
109{
110 fn from_value(value: Value) -> Result<Self, VmError> {
111 Ok(match value.into_option()?.take()? {
112 Some(some) => Some(T::from_value(some)?),
113 None => None,
114 })
115 }
116}
117
118impl UnsafeFromValue for &Option<Value> {
119 type Output = *const Option<Value>;
120 type Guard = RawRef;
121
122 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
123 Ok(Ref::into_raw(value.into_option()?.into_ref()?))
124 }
125
126 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
127 &*output
128 }
129}
130
131impl UnsafeFromValue for &mut Option<Value> {
132 type Output = *mut Option<Value>;
133 type Guard = RawMut;
134
135 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
136 Ok(Mut::into_raw(value.into_option()?.into_mut()?))
137 }
138
139 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
140 &mut *output
141 }
142}
143
144impl UnsafeFromValue for &mut Result<Value, Value> {
145 type Output = *mut Result<Value, Value>;
146 type Guard = RawMut;
147
148 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
149 Ok(Mut::into_raw(value.into_result()?.into_mut()?))
150 }
151
152 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
153 &mut *output
154 }
155}
156
157impl FromValue for String {
160 fn from_value(value: Value) -> Result<Self, VmError> {
161 match value {
162 Value::String(string) => Ok(string.borrow_ref()?.clone()),
163 Value::StaticString(string) => Ok((**string).to_owned()),
164 actual => Err(VmError::expected::<String>(actual.type_info()?)),
165 }
166 }
167}
168
169impl FromValue for Mut<String> {
170 fn from_value(value: Value) -> Result<Self, VmError> {
171 match value {
172 Value::String(string) => Ok(string.into_mut()?),
173 actual => Err(VmError::expected::<String>(actual.type_info()?)),
174 }
175 }
176}
177
178impl FromValue for Ref<String> {
179 fn from_value(value: Value) -> Result<Self, VmError> {
180 match value {
181 Value::String(string) => Ok(string.into_ref()?),
182 actual => Err(VmError::expected::<String>(actual.type_info()?)),
183 }
184 }
185}
186
187impl FromValue for Box<str> {
188 fn from_value(value: Value) -> Result<Self, VmError> {
189 let string = value.into_string()?;
190 let string = string.borrow_ref()?.clone();
191 Ok(string.into_boxed_str())
192 }
193}
194
195pub enum StrGuard {
200 RawRef(RawRef),
201 StaticString(Arc<StaticString>),
202}
203
204impl UnsafeFromValue for &str {
205 type Output = *const str;
206 type Guard = StrGuard;
207
208 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
209 Ok(match value {
210 Value::String(string) => {
211 let string = string.into_ref()?;
212 let (s, guard) = Ref::into_raw(string);
213 (unsafe { (*s).as_str() }, StrGuard::RawRef(guard))
216 }
217 Value::StaticString(string) => {
218 (string.as_ref().as_str(), StrGuard::StaticString(string))
219 }
220 actual => return Err(VmError::expected::<String>(actual.type_info()?)),
221 })
222 }
223
224 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
225 &*output
226 }
227}
228
229impl UnsafeFromValue for &mut str {
230 type Output = *mut str;
231 type Guard = Option<RawMut>;
232
233 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
234 Ok(match value {
235 Value::String(string) => {
236 let string = string.into_mut()?;
237 let (s, guard) = Mut::into_raw(string);
238 (unsafe { (*s).as_mut_str() }, Some(guard))
241 }
242 actual => {
243 return Err(VmError::expected::<String>(actual.type_info()?));
244 }
245 })
246 }
247
248 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
249 &mut *output
250 }
251}
252
253impl UnsafeFromValue for &String {
254 type Output = *const String;
255 type Guard = StrGuard;
256
257 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
258 Ok(match value {
259 Value::String(string) => {
260 let string = string.into_ref()?;
261 let (s, guard) = Ref::into_raw(string);
262 (s, StrGuard::RawRef(guard))
263 }
264 Value::StaticString(string) => (&**string, StrGuard::StaticString(string)),
265 actual => {
266 return Err(VmError::expected::<String>(actual.type_info()?));
267 }
268 })
269 }
270
271 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
272 &*output
273 }
274}
275
276impl UnsafeFromValue for &mut String {
277 type Output = *mut String;
278 type Guard = RawMut;
279
280 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
281 Ok(match value {
282 Value::String(string) => {
283 let string = string.into_mut()?;
284 let (s, guard) = Mut::into_raw(string);
285 (s, guard)
286 }
287 actual => {
288 return Err(VmError::expected::<String>(actual.type_info()?));
289 }
290 })
291 }
292
293 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
294 &mut *output
295 }
296}
297
298impl<T, E> FromValue for Result<T, E>
301where
302 T: FromValue,
303 E: FromValue,
304{
305 fn from_value(value: Value) -> Result<Self, VmError> {
306 Ok(match value.into_result()?.take()? {
307 Ok(ok) => Ok(T::from_value(ok)?),
308 Err(err) => Err(E::from_value(err)?),
309 })
310 }
311}
312
313impl UnsafeFromValue for &Result<Value, Value> {
314 type Output = *const Result<Value, Value>;
315 type Guard = RawRef;
316
317 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
318 let result = value.into_result()?;
319 let result = result.into_ref()?;
320 Ok(Ref::into_raw(result))
321 }
322
323 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
324 &*output
325 }
326}
327
328impl FromValue for () {
331 fn from_value(value: Value) -> Result<Self, VmError> {
332 Ok(value.into_unit()?)
333 }
334}
335
336impl FromValue for u8 {
337 fn from_value(value: Value) -> Result<Self, VmError> {
338 Ok(value.into_byte()?)
339 }
340}
341
342impl FromValue for bool {
343 fn from_value(value: Value) -> Result<Self, VmError> {
344 Ok(value.into_bool()?)
345 }
346}
347
348impl FromValue for char {
349 fn from_value(value: Value) -> Result<Self, VmError> {
350 Ok(value.into_char()?)
351 }
352}
353
354impl FromValue for i64 {
355 fn from_value(value: Value) -> Result<Self, VmError> {
356 Ok(value.into_integer()?)
357 }
358}
359
360macro_rules! impl_number {
361 ($ty:ty) => {
362 impl FromValue for $ty {
363 fn from_value(value: Value) -> Result<Self, VmError> {
364 use std::convert::TryInto as _;
365 let integer = value.into_integer()?;
366
367 match integer.try_into() {
368 Ok(number) => Ok(number),
369 Err(..) => Err($crate::VmError::from(
370 $crate::VmErrorKind::ValueToIntegerCoercionError {
371 from: $crate::VmIntegerRepr::from(integer),
372 to: std::any::type_name::<Self>(),
373 },
374 )),
375 }
376 }
377 }
378 };
379}
380
381impl_number!(u16);
382impl_number!(u32);
383impl_number!(u64);
384impl_number!(u128);
385impl_number!(usize);
386impl_number!(i8);
387impl_number!(i16);
388impl_number!(i32);
389impl_number!(i128);
390impl_number!(isize);
391
392impl FromValue for f64 {
393 fn from_value(value: Value) -> Result<Self, VmError> {
394 Ok(value.into_float()?)
395 }
396}
397
398impl FromValue for f32 {
399 fn from_value(value: Value) -> Result<Self, VmError> {
400 Ok(value.into_float()? as f32)
401 }
402}
403
404macro_rules! impl_map {
407 ($ty:ty) => {
408 impl<T> $crate::FromValue for $ty
409 where
410 T: $crate::FromValue,
411 {
412 fn from_value(value: $crate::Value) -> Result<Self, $crate::VmError> {
413 let object = value.into_object()?;
414 let object = object.take()?;
415
416 let mut output = <$ty>::with_capacity(object.len());
417
418 for (key, value) in object {
419 output.insert(key, T::from_value(value)?);
420 }
421
422 Ok(output)
423 }
424 }
425 };
426}
427
428impl_map!(std::collections::HashMap<String, T>);