1use core::cmp::Ordering;
2
3use crate::alloc::{self, String};
4use crate::any::AnyMarker;
5use crate::hash::Hash;
6
7use super::{
8 AnyObj, ConstValue, FromConstValue, Mut, RawAnyGuard, Ref, RuntimeError, Value, VmResult,
9};
10
11pub use rune_macros::FromValue;
85
86pub trait IntoValue {
88 #[doc(hidden)]
90 fn into_value(self) -> Value;
91}
92
93impl IntoValue for Value {
94 #[inline]
95 fn into_value(self) -> Value {
96 self
97 }
98}
99
100impl IntoValue for &Value {
101 #[inline]
102 fn into_value(self) -> Value {
103 self.clone()
104 }
105}
106
107pub fn from_value<T>(value: impl IntoValue) -> Result<T, RuntimeError>
138where
139 T: FromValue,
140{
141 T::from_value(value.into_value())
142}
143
144#[diagnostic::on_unimplemented(
175 message = "FromValue is not implemented for `{Self}`",
176 label = "FromValue is not implemented for `{Self}`",
177 note = "This probably means that `{Self}` hasn't derived rune::Any"
178)]
179pub trait FromValue: 'static + Sized {
180 fn from_value(value: Value) -> Result<Self, RuntimeError>;
182}
183
184pub trait UnsafeToMut {
186 type Guard: 'static;
191
192 unsafe fn unsafe_to_mut<'a>(value: Value) -> Result<(&'a mut Self, Self::Guard), RuntimeError>;
197}
198
199pub trait UnsafeToRef {
201 type Guard: 'static;
206
207 unsafe fn unsafe_to_ref<'a>(value: Value) -> Result<(&'a Self, Self::Guard), RuntimeError>;
212}
213
214#[deprecated = "Rune: Implementing this trait will no longer work. Use UnsafeToRef and UnsafeToMut instead."]
221pub trait UnsafeFromValue: Sized {
222 type Output: 'static;
224
225 type Guard: 'static;
230
231 fn unsafe_from_value(value: Value) -> VmResult<(Self::Output, Self::Guard)>;
241
242 unsafe fn unsafe_coerce(output: Self::Output) -> Self;
252}
253
254impl<T> FromValue for T
255where
256 T: AnyMarker,
257{
258 #[inline]
259 fn from_value(value: Value) -> Result<Self, RuntimeError> {
260 value.downcast()
261 }
262}
263
264impl<T> FromValue for Mut<T>
265where
266 T: AnyMarker,
267{
268 #[inline]
269 fn from_value(value: Value) -> Result<Self, RuntimeError> {
270 value.into_mut()
271 }
272}
273
274impl<T> FromValue for Ref<T>
275where
276 T: AnyMarker,
277{
278 #[inline]
279 fn from_value(value: Value) -> Result<Self, RuntimeError> {
280 value.into_ref()
281 }
282}
283
284impl FromValue for AnyObj {
285 #[inline]
286 fn from_value(value: Value) -> Result<Self, RuntimeError> {
287 value.into_any_obj()
288 }
289}
290
291impl FromValue for Value {
292 #[inline]
293 fn from_value(value: Value) -> Result<Self, RuntimeError> {
294 Ok(value)
295 }
296}
297
298impl<T> FromValue for Option<T>
301where
302 T: FromValue,
303{
304 #[inline]
305 fn from_value(value: Value) -> Result<Self, RuntimeError> {
306 Ok(match value.downcast::<Option<Value>>()? {
307 Some(some) => Some(T::from_value(some.clone())?),
308 None => None,
309 })
310 }
311}
312
313impl FromValue for ::rust_alloc::string::String {
314 #[inline]
315 fn from_value(value: Value) -> Result<Self, RuntimeError> {
316 let string = String::from_value(value)?;
317 let string = ::rust_alloc::string::String::from(string);
318 Ok(string)
319 }
320}
321
322impl FromValue for alloc::Box<str> {
323 #[inline]
324 fn from_value(value: Value) -> Result<Self, RuntimeError> {
325 let string = value.borrow_string_ref()?;
326 let string = alloc::Box::try_from(string.as_ref())?;
327 Ok(string)
328 }
329}
330
331#[cfg(feature = "alloc")]
332impl FromValue for ::rust_alloc::boxed::Box<str> {
333 #[inline]
334 fn from_value(value: Value) -> Result<Self, RuntimeError> {
335 let string = value.borrow_string_ref()?;
336 let string = ::rust_alloc::boxed::Box::<str>::from(string.as_ref());
337 Ok(string)
338 }
339}
340
341impl FromValue for Ref<str> {
342 #[inline]
343 fn from_value(value: Value) -> Result<Self, RuntimeError> {
344 Ok(Ref::map(Ref::<String>::from_value(value)?, String::as_str))
345 }
346}
347
348impl UnsafeToRef for str {
349 type Guard = RawAnyGuard;
350
351 #[inline]
352 unsafe fn unsafe_to_ref<'a>(value: Value) -> Result<(&'a Self, Self::Guard), RuntimeError> {
353 let string = value.into_ref::<String>()?;
354 let (string, guard) = Ref::into_raw(string);
355 Ok((string.as_ref().as_str(), guard))
356 }
357}
358
359impl UnsafeToMut for str {
360 type Guard = RawAnyGuard;
361
362 #[inline]
363 unsafe fn unsafe_to_mut<'a>(value: Value) -> Result<(&'a mut Self, Self::Guard), RuntimeError> {
364 let string = value.into_mut::<String>()?;
365 let (mut string, guard) = Mut::into_raw(string);
366 Ok((string.as_mut().as_mut_str(), guard))
367 }
368}
369
370impl<T, E> FromValue for Result<T, E>
371where
372 T: FromValue,
373 E: FromValue,
374{
375 #[inline]
376 fn from_value(value: Value) -> Result<Self, RuntimeError> {
377 Ok(match value.downcast::<Result<Value, Value>>()? {
378 Ok(ok) => Result::Ok(T::from_value(ok.clone())?),
379 Err(err) => Result::Err(E::from_value(err.clone())?),
380 })
381 }
382}
383
384impl FromValue for bool {
385 #[inline]
386 fn from_value(value: Value) -> Result<Self, RuntimeError> {
387 value.as_bool()
388 }
389}
390
391impl FromConstValue for bool {
392 #[inline]
393 fn from_const_value(value: ConstValue) -> Result<Self, RuntimeError> {
394 value.as_bool()
395 }
396}
397
398impl FromValue for char {
399 #[inline]
400 fn from_value(value: Value) -> Result<Self, RuntimeError> {
401 value.as_char()
402 }
403}
404
405impl FromConstValue for char {
406 #[inline]
407 fn from_const_value(value: ConstValue) -> Result<Self, RuntimeError> {
408 value.as_char()
409 }
410}
411
412macro_rules! impl_integer {
413 ($($ty:ty),* $(,)?) => {
414 $(
415 impl FromValue for $ty {
416 #[inline]
417 fn from_value(value: Value) -> Result<Self, RuntimeError> {
418 value.as_integer()
419 }
420 }
421
422 impl FromConstValue for $ty {
423 #[inline]
424 fn from_const_value(value: ConstValue) -> Result<Self, RuntimeError> {
425 value.as_integer()
426 }
427 }
428 )*
429 };
430}
431
432impl_integer!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
433
434impl FromValue for f64 {
435 #[inline]
436 fn from_value(value: Value) -> Result<Self, RuntimeError> {
437 value.as_float()
438 }
439}
440
441impl FromValue for f32 {
442 #[inline]
443 fn from_value(value: Value) -> Result<Self, RuntimeError> {
444 Ok(value.as_float()? as f32)
445 }
446}
447
448cfg_std! {
449 macro_rules! impl_map {
450 ($ty:ty, $key:ty) => {
451 impl<T> FromValue for $ty
452 where
453 T: FromValue,
454 {
455 fn from_value(value: Value) -> Result<Self, RuntimeError> {
456 let object = value.downcast::<$crate::runtime::Object>()?;
457
458 let mut output = <$ty>::with_capacity(object.len());
459
460 for (key, value) in object {
461 let key = <$key>::try_from(key)?;
462 let value = <T>::from_value(value)?;
463 output.insert(key, value);
464 }
465
466 Ok(output)
467 }
468 }
469 };
470 }
471
472 impl_map!(::std::collections::HashMap<String, T>, String);
473 impl_map!(::std::collections::HashMap<::rust_alloc::string::String, T>, ::rust_alloc::string::String);
474}
475
476macro_rules! impl_try_map {
477 ($ty:ty, $key:ty) => {
478 impl<T> FromValue for $ty
479 where
480 T: FromValue,
481 {
482 fn from_value(value: Value) -> Result<Self, RuntimeError> {
483 let object = value.downcast::<$crate::runtime::Object>()?;
484
485 let mut output = <$ty>::try_with_capacity(object.len())?;
486
487 for (key, value) in object {
488 let key = <$key>::try_from(key)?;
489 let value = <T>::from_value(value)?;
490 output.try_insert(key, value)?;
491 }
492
493 Ok(output)
494 }
495 }
496 };
497}
498
499impl_try_map!(alloc::HashMap<String, T>, String);
500#[cfg(feature = "alloc")]
501impl_try_map!(alloc::HashMap<::rust_alloc::string::String, T>, ::rust_alloc::string::String);
502
503impl FromValue for Ordering {
504 #[inline]
505 fn from_value(value: Value) -> Result<Self, RuntimeError> {
506 value.as_ordering()
507 }
508}
509
510impl FromValue for Hash {
511 #[inline]
512 fn from_value(value: Value) -> Result<Self, RuntimeError> {
513 value.as_hash()
514 }
515}