rune/runtime/
value.rs

1#[macro_use]
2mod macros;
3
4#[cfg(test)]
5mod tests;
6
7mod inline;
8pub use self::inline::Inline;
9
10#[cfg(feature = "serde")]
11mod serde;
12
13mod rtti;
14pub(crate) use self::rtti::RttiKind;
15pub use self::rtti::{Accessor, Rtti};
16
17mod data;
18pub use self::data::{EmptyStruct, Struct, TupleStruct};
19
20mod any_sequence;
21pub use self::any_sequence::AnySequence;
22pub(crate) use self::any_sequence::AnySequenceTakeError;
23
24use core::any;
25use core::cmp::Ordering;
26use core::fmt;
27use core::mem::replace;
28use core::ptr::NonNull;
29
30use crate::alloc::fmt::TryWrite;
31use crate::alloc::prelude::*;
32use crate::alloc::{self, String};
33use crate::compile::meta;
34use crate::sync::Arc;
35use crate::{Any, Hash, TypeHash};
36
37use super::{
38    AccessError, AnyObj, AnyObjDrop, BorrowMut, BorrowRef, CallResultOnly, ConstValue,
39    ConstValueKind, DynGuardedArgs, EnvProtocolCaller, Formatter, FromValue, Future, Hasher,
40    Iterator, MaybeTypeOf, Mut, Object, OwnedTuple, Protocol, ProtocolCaller, RawAnyObjGuard, Ref,
41    RuntimeError, Shared, Snapshot, Tuple, Type, TypeInfo, Vec, VmError, VmErrorKind,
42    VmIntegerRepr,
43};
44
45/// Defined guard for a reference value.
46///
47/// See [`Value::from_ref`].
48pub struct ValueRefGuard {
49    #[allow(unused)]
50    guard: AnyObjDrop,
51}
52
53/// Defined guard for a reference value.
54///
55/// See [`Value::from_mut`].
56pub struct ValueMutGuard {
57    #[allow(unused)]
58    guard: AnyObjDrop,
59}
60
61/// The guard returned by [`Value::into_any_mut_ptr`].
62pub struct RawValueGuard {
63    #[allow(unused)]
64    guard: RawAnyObjGuard,
65}
66
67#[derive(Clone)]
68pub(crate) enum Repr {
69    Inline(Inline),
70    Dynamic(AnySequence<Arc<Rtti>, Value>),
71    Any(AnyObj),
72}
73
74impl Repr {
75    #[inline]
76    pub(crate) fn type_info(&self) -> TypeInfo {
77        match self {
78            Repr::Inline(value) => value.type_info(),
79            Repr::Dynamic(value) => value.type_info(),
80            Repr::Any(value) => value.type_info(),
81        }
82    }
83}
84
85/// An entry on the stack.
86pub struct Value {
87    repr: Repr,
88}
89
90impl Value {
91    /// Take a mutable value, replacing the original location with an empty value.
92    #[inline]
93    pub fn take(value: &mut Self) -> Self {
94        replace(value, Self::empty())
95    }
96
97    /// Construct a value from a type that implements [`Any`] which owns the
98    /// underlying value.
99    pub fn new<T>(data: T) -> alloc::Result<Self>
100    where
101        T: Any,
102    {
103        Ok(Self {
104            repr: Repr::Any(AnyObj::new(data)?),
105        })
106    }
107
108    /// Construct an Any that wraps a pointer.
109    ///
110    /// # Safety
111    ///
112    /// Caller must ensure that the returned `Value` doesn't outlive the
113    /// reference it is wrapping.
114    ///
115    /// This would be an example of incorrect use:
116    ///
117    /// ```no_run
118    /// use rune::Any;
119    /// use rune::runtime::Value;
120    ///
121    /// #[derive(Any)]
122    /// struct Foo(u32);
123    ///
124    /// let mut v = Foo(1u32);
125    ///
126    /// unsafe {
127    ///     let (any, guard) = unsafe { Value::from_ref(&v)? };
128    ///     drop(v);
129    ///     // any use of `any` beyond here is undefined behavior.
130    /// }
131    /// # Ok::<_, rune::support::Error>(())
132    /// ```
133    ///
134    /// # Examples
135    ///
136    /// ```
137    /// use rune::Any;
138    /// use rune::runtime::Value;
139    ///
140    /// #[derive(Any)]
141    /// struct Foo(u32);
142    ///
143    /// let mut v = Foo(1u32);
144    ///
145    /// unsafe {
146    ///     let (any, guard) = Value::from_ref(&mut v)?;
147    ///     let b = any.borrow_ref::<Foo>()?;
148    ///     assert_eq!(b.0, 1u32);
149    /// }
150    /// # Ok::<_, rune::support::Error>(())
151    /// ```
152    pub unsafe fn from_ref<T>(data: &T) -> alloc::Result<(Self, ValueRefGuard)>
153    where
154        T: Any,
155    {
156        let value = AnyObj::from_ref(data)?;
157        let (value, guard) = AnyObj::into_drop_guard(value);
158
159        let guard = ValueRefGuard { guard };
160
161        Ok((
162            Self {
163                repr: Repr::Any(value),
164            },
165            guard,
166        ))
167    }
168
169    /// Construct a value that wraps a mutable pointer.
170    ///
171    /// # Safety
172    ///
173    /// Caller must ensure that the returned `Value` doesn't outlive the
174    /// reference it is wrapping.
175    ///
176    /// This would be an example of incorrect use:
177    ///
178    /// ```no_run
179    /// use rune::Any;
180    /// use rune::runtime::Value;
181    ///
182    /// #[derive(Any)]
183    /// struct Foo(u32);
184    ///
185    /// let mut v = Foo(1u32);
186    /// unsafe {
187    ///     let (any, guard) = Value::from_mut(&mut v)?;
188    ///     drop(v);
189    ///     // any use of value beyond here is undefined behavior.
190    /// }
191    /// # Ok::<_, rune::support::Error>(())
192    /// ```
193    ///
194    /// # Examples
195    ///
196    /// ```
197    /// use rune::Any;
198    /// use rune::runtime::Value;
199    ///
200    /// #[derive(Any)]
201    /// struct Foo(u32);
202    ///
203    /// let mut v = Foo(1u32);
204    ///
205    /// unsafe {
206    ///     let (any, guard) = Value::from_mut(&mut v)?;
207    ///
208    ///     if let Ok(mut v) = any.borrow_mut::<Foo>() {
209    ///         v.0 += 1;
210    ///     }
211    ///
212    ///     drop(guard);
213    ///     assert!(any.borrow_mut::<Foo>().is_err());
214    ///     drop(any);
215    /// }
216    ///
217    /// assert_eq!(v.0, 2);
218    /// # Ok::<_, rune::support::Error>(())
219    /// ```
220    pub unsafe fn from_mut<T>(data: &mut T) -> alloc::Result<(Self, ValueMutGuard)>
221    where
222        T: Any,
223    {
224        let value = AnyObj::from_mut(data)?;
225        let (value, guard) = AnyObj::into_drop_guard(value);
226
227        let guard = ValueMutGuard { guard };
228
229        Ok((
230            Self {
231                repr: Repr::Any(value),
232            },
233            guard,
234        ))
235    }
236
237    /// Optionally get the snapshot of the value if available.
238    pub(crate) fn snapshot(&self) -> Option<Snapshot> {
239        match &self.repr {
240            Repr::Dynamic(value) => Some(value.snapshot()),
241            Repr::Any(value) => Some(value.snapshot()),
242            _ => None,
243        }
244    }
245
246    /// Test if the value is writable.
247    ///
248    /// # Examples
249    ///
250    /// ```
251    /// use rune::{Any, Value};
252    ///
253    /// #[derive(Any)]
254    /// struct Struct(u32);
255    ///
256    /// let value = Value::new(Struct(42))?;
257    ///
258    /// {
259    ///     assert!(value.is_writable());
260    ///
261    ///     let borrowed = value.borrow_mut::<Struct>()?;
262    ///     assert!(!value.is_writable());
263    ///     drop(borrowed);
264    ///     assert!(value.is_writable());
265    /// }
266    ///
267    /// let foo = Struct(42);
268    ///
269    /// {
270    ///     let (value, guard) = unsafe { Value::from_ref(&foo)? };
271    ///     assert!(value.is_readable());
272    ///     assert!(!value.is_writable());
273    /// }
274    ///
275    /// let mut foo = Struct(42);
276    ///
277    /// {
278    ///     let (value, guard) = unsafe { Value::from_mut(&mut foo)? };
279    ///     assert!(value.is_readable());
280    ///     assert!(value.is_writable());
281    /// }
282    /// # Ok::<_, rune::support::Error>(())
283    /// ```
284    pub fn is_writable(&self) -> bool {
285        match self.repr {
286            Repr::Inline(Inline::Empty) => false,
287            Repr::Inline(..) => true,
288            Repr::Dynamic(ref value) => value.is_writable(),
289            Repr::Any(ref any) => any.is_writable(),
290        }
291    }
292
293    /// Test if a value is readable.
294    ///
295    /// # Examples
296    ///
297    /// ```
298    /// use rune::{Any, Value};
299    ///
300    /// #[derive(Any)]
301    /// struct Struct(u32);
302    ///
303    /// let value = Value::new(Struct(42))?;
304    ///
305    /// {
306    ///     assert!(value.is_writable());
307    ///
308    ///     let borrowed = value.borrow_mut::<Struct>()?;
309    ///     assert!(!value.is_writable());
310    ///     drop(borrowed);
311    ///     assert!(value.is_writable());
312    /// }
313    ///
314    /// let foo = Struct(42);
315    ///
316    /// {
317    ///     let (value, guard) = unsafe { Value::from_ref(&foo)? };
318    ///     assert!(value.is_readable());
319    ///     assert!(!value.is_writable());
320    /// }
321    ///
322    /// let mut foo = Struct(42);
323    ///
324    /// {
325    ///     let (value, guard) = unsafe { Value::from_mut(&mut foo)? };
326    ///     assert!(value.is_readable());
327    ///     assert!(value.is_writable());
328    /// }
329    /// # Ok::<_, rune::support::Error>(())
330    /// ```
331    pub fn is_readable(&self) -> bool {
332        match &self.repr {
333            Repr::Inline(Inline::Empty) => false,
334            Repr::Inline(..) => true,
335            Repr::Dynamic(ref value) => value.is_readable(),
336            Repr::Any(ref any) => any.is_readable(),
337        }
338    }
339
340    /// Construct a unit value.
341    pub(crate) const fn unit() -> Self {
342        Self {
343            repr: Repr::Inline(Inline::Unit),
344        }
345    }
346
347    /// Construct an empty value.
348    pub const fn empty() -> Self {
349        Self {
350            repr: Repr::Inline(Inline::Empty),
351        }
352    }
353
354    /// Format the value using the [`DISPLAY_FMT`] protocol.
355    ///
356    /// You must use [`Vm::with`] to specify which virtual machine this function
357    /// is called inside.
358    ///
359    /// [`Vm::with`]: crate::Vm::with
360    ///
361    /// # Errors
362    ///
363    /// This function errors if called outside of a virtual machine.
364    ///
365    /// [`DISPLAY_FMT`]: Protocol::DISPLAY_FMT
366    pub fn display_fmt(&self, f: &mut Formatter) -> Result<(), VmError> {
367        self.display_fmt_with(f, &mut EnvProtocolCaller)
368    }
369
370    /// Internal impl of display_fmt with a customizable caller.
371    #[cfg_attr(feature = "bench", inline(never))]
372    pub(crate) fn display_fmt_with(
373        &self,
374        f: &mut Formatter,
375        caller: &mut dyn ProtocolCaller,
376    ) -> Result<(), VmError> {
377        'fallback: {
378            match self.as_ref() {
379                Repr::Inline(value) => match value {
380                    Inline::Char(c) => {
381                        f.try_write_char(*c)?;
382                    }
383                    Inline::Unsigned(byte) => {
384                        let mut buffer = itoa::Buffer::new();
385                        f.try_write_str(buffer.format(*byte))?;
386                    }
387                    Inline::Signed(integer) => {
388                        let mut buffer = itoa::Buffer::new();
389                        f.try_write_str(buffer.format(*integer))?;
390                    }
391                    Inline::Float(float) => {
392                        let mut buffer = ryu::Buffer::new();
393                        f.try_write_str(buffer.format(*float))?;
394                    }
395                    Inline::Bool(bool) => {
396                        write!(f, "{bool}")?;
397                    }
398                    _ => {
399                        break 'fallback;
400                    }
401                },
402                _ => {
403                    break 'fallback;
404                }
405            }
406
407            return Ok(());
408        };
409
410        let mut args = DynGuardedArgs::new((f,));
411
412        let result = caller.call_protocol_fn(&Protocol::DISPLAY_FMT, self.clone(), &mut args)?;
413
414        <()>::from_value(result)?;
415        Ok(())
416    }
417
418    /// Perform a shallow clone of the value using the [`CLONE`] protocol.
419    ///
420    /// You must use [`Vm::with`] to specify which virtual machine this function
421    /// is called inside.
422    ///
423    /// [`Vm::with`]: crate::Vm::with
424    ///
425    /// # Errors
426    ///
427    /// This function errors if called outside of a virtual machine.
428    ///
429    /// [`CLONE`]: Protocol::CLONE
430    pub fn clone_(&self) -> Result<Self, VmError> {
431        self.clone_with(&mut EnvProtocolCaller)
432    }
433
434    pub(crate) fn clone_with(&self, caller: &mut dyn ProtocolCaller) -> Result<Value, VmError> {
435        match self.as_ref() {
436            Repr::Inline(value) => {
437                return Ok(Self {
438                    repr: Repr::Inline(*value),
439                });
440            }
441            Repr::Dynamic(value) => {
442                // TODO: This type of cloning should be deep, not shallow.
443                return Ok(Self {
444                    repr: Repr::Dynamic(value.clone()),
445                });
446            }
447            Repr::Any(..) => {}
448        }
449
450        caller.call_protocol_fn(&Protocol::CLONE, self.clone(), &mut ())
451    }
452
453    /// Debug format the value using the [`DEBUG_FMT`] protocol.
454    ///
455    /// You must use [`Vm::with`] to specify which virtual machine this function
456    /// is called inside.
457    ///
458    /// [`Vm::with`]: crate::Vm::with
459    ///
460    /// # Errors
461    ///
462    /// This function errors if called outside of a virtual machine.
463    ///
464    /// [`DEBUG_FMT`]: Protocol::DEBUG_FMT
465    pub fn debug_fmt(&self, f: &mut Formatter) -> Result<(), VmError> {
466        self.debug_fmt_with(f, &mut EnvProtocolCaller)
467    }
468
469    /// Internal impl of debug_fmt with a customizable caller.
470    pub(crate) fn debug_fmt_with(
471        &self,
472        f: &mut Formatter,
473        caller: &mut dyn ProtocolCaller,
474    ) -> Result<(), VmError> {
475        match &self.repr {
476            Repr::Inline(value) => {
477                write!(f, "{value:?}")?;
478            }
479            Repr::Dynamic(ref value) => {
480                value.debug_fmt_with(f, caller)?;
481            }
482            Repr::Any(..) => {
483                // reborrow f to avoid moving it
484                let mut args = DynGuardedArgs::new((&mut *f,));
485
486                match caller.try_call_protocol_fn(&Protocol::DEBUG_FMT, self.clone(), &mut args)? {
487                    CallResultOnly::Ok(value) => {
488                        <()>::from_value(value)?;
489                    }
490                    CallResultOnly::Unsupported(value) => match &value.repr {
491                        Repr::Inline(value) => {
492                            write!(f, "{value:?}")?;
493                        }
494                        Repr::Dynamic(value) => {
495                            let ty = value.type_info();
496                            write!(f, "<{ty} object at {value:p}>")?;
497                        }
498                        Repr::Any(value) => {
499                            let ty = value.type_info();
500                            write!(f, "<{ty} object at {value:p}>")?;
501                        }
502                    },
503                }
504            }
505        }
506
507        Ok(())
508    }
509
510    /// Convert value into an iterator using the [`Protocol::INTO_ITER`]
511    /// protocol.
512    ///
513    /// You must use [`Vm::with`] to specify which virtual machine this function
514    /// is called inside.
515    ///
516    /// [`Vm::with`]: crate::Vm::with
517    ///
518    /// # Errors
519    ///
520    /// This function will error if called outside of a virtual machine context.
521    pub fn into_iter(self) -> Result<Iterator, VmError> {
522        self.into_iter_with(&mut EnvProtocolCaller)
523    }
524
525    pub(crate) fn into_iter_with(
526        self,
527        caller: &mut dyn ProtocolCaller,
528    ) -> Result<Iterator, VmError> {
529        let value = caller.call_protocol_fn(&Protocol::INTO_ITER, self, &mut ())?;
530        Ok(Iterator::new(value))
531    }
532
533    /// Retrieves a human readable type name for the current value.
534    ///
535    /// You must use [`Vm::with`] to specify which virtual machine this function
536    /// is called inside.
537    ///
538    /// [`Vm::with`]: crate::Vm::with
539    ///
540    /// # Errors
541    ///
542    /// This function errors in case the provided type cannot be converted into
543    /// a name without the use of a [`Vm`] and one is not provided through the
544    /// environment.
545    ///
546    /// [`Vm`]: crate::Vm
547    pub fn into_type_name(self) -> Result<String, VmError> {
548        let hash = Hash::associated_function(self.type_hash(), &Protocol::INTO_TYPE_NAME);
549
550        crate::runtime::env::shared(|context, unit| {
551            if let Some(name) = context.constant(&hash) {
552                match name.as_kind() {
553                    ConstValueKind::String(s) => return Ok(String::try_from(s.as_ref())?),
554                    _ => {
555                        return Err(VmError::new(VmErrorKind::expected::<String>(
556                            name.type_info(),
557                        )))
558                    }
559                }
560            }
561
562            if let Some(name) = unit.constant(&hash) {
563                match name.as_kind() {
564                    ConstValueKind::String(s) => return Ok(String::try_from(s.as_ref())?),
565                    _ => {
566                        return Err(VmError::new(VmErrorKind::expected::<String>(
567                            name.type_info(),
568                        )))
569                    }
570                }
571            }
572
573            Ok(self.type_info().try_to_string()?)
574        })
575    }
576
577    /// Construct a vector.
578    pub fn vec(vec: alloc::Vec<Value>) -> alloc::Result<Self> {
579        let data = Vec::from(vec);
580        Value::try_from(data)
581    }
582
583    /// Construct a tuple.
584    pub fn tuple(vec: alloc::Vec<Value>) -> alloc::Result<Self> {
585        Value::try_from(OwnedTuple::try_from(vec)?)
586    }
587
588    /// Construct an empty.
589    pub fn empty_struct(rtti: Arc<Rtti>) -> alloc::Result<Self> {
590        Ok(Value::from(AnySequence::new(rtti, [])?))
591    }
592
593    /// Construct a typed tuple.
594    pub fn tuple_struct(
595        rtti: Arc<Rtti>,
596        data: impl IntoIterator<IntoIter: ExactSizeIterator, Item = Value>,
597    ) -> alloc::Result<Self> {
598        Ok(Value::from(AnySequence::new(rtti, data)?))
599    }
600
601    /// Drop the interior value.
602    ///
603    /// This consumes any live references of the value and accessing them in the
604    /// future will result in an error.
605    pub(crate) fn drop(self) -> Result<(), VmError> {
606        match self.repr {
607            Repr::Dynamic(value) => {
608                value.drop()?;
609            }
610            Repr::Any(value) => {
611                value.drop()?;
612            }
613            _ => {}
614        }
615
616        Ok(())
617    }
618
619    /// Move the interior value.
620    pub(crate) fn move_(self) -> Result<Self, VmError> {
621        match self.repr {
622            Repr::Dynamic(value) => Ok(Value {
623                repr: Repr::Dynamic(value.take()?),
624            }),
625            Repr::Any(value) => Ok(Value {
626                repr: Repr::Any(value.take()?),
627            }),
628            repr => Ok(Value { repr }),
629        }
630    }
631
632    /// Try to coerce value into a usize.
633    #[inline]
634    pub fn as_usize(&self) -> Result<usize, RuntimeError> {
635        self.as_integer()
636    }
637
638    /// Get the value as a string.
639    #[deprecated(
640        note = "For consistency with other methods, this has been renamed Value::borrow_string_ref"
641    )]
642    #[inline]
643    pub fn as_string(&self) -> Result<BorrowRef<'_, str>, RuntimeError> {
644        self.borrow_string_ref()
645    }
646
647    /// Borrow the interior value as a string reference.
648    pub fn borrow_string_ref(&self) -> Result<BorrowRef<'_, str>, RuntimeError> {
649        let string = self.borrow_ref::<String>()?;
650        Ok(BorrowRef::map(string, String::as_str))
651    }
652
653    /// Take the current value as a string.
654    #[inline]
655    pub fn into_string(self) -> Result<String, RuntimeError> {
656        match self.take_repr() {
657            Repr::Any(value) => Ok(value.downcast()?),
658            actual => Err(RuntimeError::expected::<String>(actual.type_info())),
659        }
660    }
661
662    /// Coerce into type value.
663    #[doc(hidden)]
664    #[inline]
665    pub fn as_type_value(&self) -> Result<TypeValue<'_>, RuntimeError> {
666        match self.as_ref() {
667            Repr::Inline(value) => match value {
668                Inline::Unit => Ok(TypeValue::Unit),
669                value => Ok(TypeValue::NotTypedInline(NotTypedInline(*value))),
670            },
671            Repr::Dynamic(value) => match value.rtti().kind {
672                RttiKind::Empty => Ok(TypeValue::EmptyStruct(EmptyStruct { rtti: value.rtti() })),
673                RttiKind::Tuple => Ok(TypeValue::TupleStruct(TupleStruct {
674                    rtti: value.rtti(),
675                    data: value.borrow_ref()?,
676                })),
677                RttiKind::Struct => Ok(TypeValue::Struct(Struct {
678                    rtti: value.rtti(),
679                    data: value.borrow_ref()?,
680                })),
681            },
682            Repr::Any(value) => match value.type_hash() {
683                OwnedTuple::HASH => Ok(TypeValue::Tuple(value.borrow_ref()?)),
684                Object::HASH => Ok(TypeValue::Object(value.borrow_ref()?)),
685                _ => Ok(TypeValue::NotTypedAnyObj(NotTypedAnyObj(value))),
686            },
687        }
688    }
689
690    /// Coerce into a unit.
691    #[inline]
692    pub fn into_unit(&self) -> Result<(), RuntimeError> {
693        match self.as_ref() {
694            Repr::Inline(Inline::Unit) => Ok(()),
695            value => Err(RuntimeError::expected::<()>(value.type_info())),
696        }
697    }
698
699    inline_into! {
700        /// Coerce into [`Ordering`].
701        Ordering(Ordering),
702        as_ordering,
703        as_ordering_mut,
704    }
705
706    inline_into! {
707        /// Coerce into [`Hash`][crate::Hash].
708        Hash(Hash),
709        as_hash,
710        as_hash_mut,
711    }
712
713    inline_into! {
714        /// Coerce into [`bool`].
715        Bool(bool),
716        as_bool,
717        as_bool_mut,
718    }
719
720    inline_into! {
721        /// Coerce into [`char`].
722        Char(char),
723        as_char,
724        as_char_mut,
725    }
726
727    inline_into! {
728        /// Coerce into [`i64`] integer.
729        Signed(i64),
730        as_signed,
731        as_signed_mut,
732    }
733
734    inline_into! {
735        /// Coerce into [`u64`] unsigned integer.
736        Unsigned(u64),
737        as_unsigned,
738        as_unsigned_mut,
739    }
740
741    inline_into! {
742        /// Coerce into [`f64`] float.
743        Float(f64),
744        as_float,
745        as_float_mut,
746    }
747
748    inline_into! {
749        /// Coerce into [`Type`].
750        Type(Type),
751        as_type,
752        as_type_mut,
753    }
754
755    /// Borrow as a tuple.
756    ///
757    /// This ensures that the value has read access to the underlying value
758    /// and does not consume it.
759    #[inline]
760    pub fn borrow_tuple_ref(&self) -> Result<BorrowRef<'_, Tuple>, RuntimeError> {
761        match self.as_ref() {
762            Repr::Inline(Inline::Unit) => Ok(BorrowRef::from_static(Tuple::new(&[]))),
763            Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
764            Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
765            Repr::Any(value) => {
766                let value = value.borrow_ref::<OwnedTuple>()?;
767                let value = BorrowRef::map(value, OwnedTuple::as_ref);
768                Ok(value)
769            }
770        }
771    }
772
773    /// Borrow as a tuple as mutable.
774    ///
775    /// This ensures that the value has write access to the underlying value and
776    /// does not consume it.
777    #[inline]
778    pub fn borrow_tuple_mut(&self) -> Result<BorrowMut<'_, Tuple>, RuntimeError> {
779        match self.as_ref() {
780            Repr::Inline(Inline::Unit) => Ok(BorrowMut::from_ref(Tuple::new_mut(&mut []))),
781            Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
782            Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
783            Repr::Any(value) => {
784                let value = value.borrow_mut::<OwnedTuple>()?;
785                let value = BorrowMut::map(value, OwnedTuple::as_mut);
786                Ok(value)
787            }
788        }
789    }
790
791    /// Borrow as an owned tuple reference.
792    ///
793    /// This ensures that the value has read access to the underlying value and
794    /// does not consume it.
795    #[inline]
796    pub fn into_tuple(&self) -> Result<Box<Tuple>, RuntimeError> {
797        match self.as_ref() {
798            Repr::Inline(Inline::Unit) => Ok(Tuple::from_boxed(Box::default())),
799            Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
800            Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
801            Repr::Any(value) => Ok(value.clone().downcast::<OwnedTuple>()?.into_boxed_tuple()),
802        }
803    }
804
805    /// Borrow as an owned tuple reference.
806    ///
807    /// This ensures that the value has read access to the underlying value and
808    /// does not consume it.
809    #[inline]
810    pub fn into_tuple_ref(&self) -> Result<Ref<Tuple>, RuntimeError> {
811        match self.as_ref() {
812            Repr::Inline(Inline::Unit) => Ok(Ref::from_static(Tuple::new(&[]))),
813            Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
814            Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
815            Repr::Any(value) => {
816                let value = value.clone().into_ref::<OwnedTuple>()?;
817                let value = Ref::map(value, OwnedTuple::as_ref);
818                Ok(value)
819            }
820        }
821    }
822
823    /// Borrow as an owned tuple mutable.
824    ///
825    /// This ensures that the value has write access to the underlying value and
826    /// does not consume it.
827    #[inline]
828    pub fn into_tuple_mut(&self) -> Result<Mut<Tuple>, RuntimeError> {
829        match self.as_ref() {
830            Repr::Inline(Inline::Unit) => Ok(Mut::from_static(Tuple::new_mut(&mut []))),
831            Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
832            Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
833            Repr::Any(value) => {
834                let value = value.clone().into_mut::<OwnedTuple>()?;
835                let value = Mut::map(value, OwnedTuple::as_mut);
836                Ok(value)
837            }
838        }
839    }
840
841    /// Coerce into an [`AnyObj`].
842    #[inline]
843    pub fn into_any_obj(self) -> Result<AnyObj, RuntimeError> {
844        match self.repr {
845            Repr::Inline(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
846            Repr::Dynamic(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
847            Repr::Any(value) => Ok(value),
848        }
849    }
850
851    /// Coerce into a [`Shared<T>`].
852    ///
853    /// This type checks and coerces the value into a type which statically
854    /// guarantees that the underlying type is of the given type.
855    #[inline]
856    pub fn into_shared<T>(self) -> Result<Shared<T>, RuntimeError>
857    where
858        T: Any,
859    {
860        match self.repr {
861            Repr::Inline(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
862            Repr::Dynamic(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
863            Repr::Any(value) => Ok(value.into_shared()?),
864        }
865    }
866
867    /// Coerce into a future, or convert into a future using the
868    /// [Protocol::INTO_FUTURE] protocol.
869    ///
870    /// You must use [`Vm::with`] to specify which virtual machine this function
871    /// is called inside.
872    ///
873    /// [`Vm::with`]: crate::Vm::with
874    ///
875    /// # Errors
876    ///
877    /// This function errors in case the provided type cannot be converted into
878    /// a future without the use of a [`Vm`] and one is not provided through the
879    /// environment.
880    ///
881    /// [`Vm`]: crate::Vm
882    #[inline]
883    pub fn into_future(self) -> Result<Future, RuntimeError> {
884        let target = match self.repr {
885            Repr::Any(value) => match value.type_hash() {
886                Future::HASH => {
887                    return Ok(value.downcast::<Future>()?);
888                }
889                _ => Value::from(value),
890            },
891            repr => Value::from(repr),
892        };
893
894        let value = EnvProtocolCaller.call_protocol_fn(&Protocol::INTO_FUTURE, target, &mut ())?;
895
896        Future::from_value(value)
897    }
898
899    /// Try to coerce value into a typed reference.
900    ///
901    /// # Safety
902    ///
903    /// The returned pointer is only valid to dereference as long as the
904    /// returned guard is live.
905    #[inline]
906    pub fn into_any_ref_ptr<T>(self) -> Result<(NonNull<T>, RawValueGuard), RuntimeError>
907    where
908        T: Any,
909    {
910        match self.repr {
911            Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
912            Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
913            Repr::Any(value) => {
914                let (ptr, guard) = value.borrow_ref_ptr::<T>()?;
915                let guard = RawValueGuard { guard };
916                Ok((ptr, guard))
917            }
918        }
919    }
920
921    /// Try to coerce value into a typed mutable reference.
922    ///
923    /// # Safety
924    ///
925    /// The returned pointer is only valid to dereference as long as the
926    /// returned guard is live.
927    #[inline]
928    #[doc(hidden)]
929    pub fn into_any_mut_ptr<T>(self) -> Result<(NonNull<T>, RawValueGuard), RuntimeError>
930    where
931        T: Any,
932    {
933        match self.repr {
934            Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
935            Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
936            Repr::Any(value) => {
937                let (ptr, guard) = value.borrow_mut_ptr::<T>()?;
938                let guard = RawValueGuard { guard };
939                Ok((ptr, guard))
940            }
941        }
942    }
943
944    /// Downcast the value into a stored value that implements `Any`.
945    ///
946    /// This takes the interior value, making it inaccessible to other owned
947    /// references.
948    ///
949    /// You should usually prefer to use [`rune::from_value`] instead of this
950    /// directly.
951    ///
952    /// [`rune::from_value`]: crate::from_value
953    ///
954    /// # Examples
955    ///
956    /// ```
957    /// use rune::Value;
958    /// use rune::alloc::String;
959    ///
960    /// let a = Value::try_from("Hello World")?;
961    /// let b = a.clone();
962    ///
963    /// assert!(b.borrow_ref::<String>().is_ok());
964    ///
965    /// // NB: The interior representation of the stored string is from rune-alloc.
966    /// let a = a.downcast::<String>()?;
967    ///
968    /// assert!(b.borrow_ref::<String>().is_err());
969    ///
970    /// assert_eq!(a, "Hello World");
971    /// # Ok::<_, rune::support::Error>(())
972    /// ```
973    #[inline]
974    pub fn downcast<T>(self) -> Result<T, RuntimeError>
975    where
976        T: Any,
977    {
978        match self.repr {
979            Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
980            Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
981            Repr::Any(value) => Ok(value.downcast::<T>()?),
982        }
983    }
984
985    /// Borrow the value as a typed reference of type `T`.
986    ///
987    /// # Examples
988    ///
989    /// ```
990    /// use rune::Value;
991    /// use rune::alloc::String;
992    ///
993    /// let a = Value::try_from("Hello World")?;
994    /// let b = a.clone();
995    ///
996    /// assert!(b.borrow_ref::<String>().is_ok());
997    ///
998    /// // NB: The interior representation of the stored string is from rune-alloc.
999    /// let a = a.downcast::<String>()?;
1000    ///
1001    /// assert!(b.borrow_ref::<String>().is_err());
1002    ///
1003    /// assert_eq!(a, "Hello World");
1004    /// # Ok::<_, rune::support::Error>(())
1005    /// ```
1006    #[inline]
1007    pub fn borrow_ref<T>(&self) -> Result<BorrowRef<'_, T>, RuntimeError>
1008    where
1009        T: Any,
1010    {
1011        match &self.repr {
1012            Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1013            Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1014            Repr::Any(value) => Ok(value.borrow_ref()?),
1015        }
1016    }
1017
1018    /// Try to coerce value into a typed reference of type `T`.
1019    ///
1020    /// You should usually prefer to use [`rune::from_value`] instead of this
1021    /// directly.
1022    ///
1023    /// [`rune::from_value`]: crate::from_value
1024    ///
1025    /// # Examples
1026    ///
1027    /// ```
1028    /// use rune::Value;
1029    /// use rune::alloc::String;
1030    ///
1031    /// let mut a = Value::try_from("Hello World")?;
1032    /// let b = a.clone();
1033    ///
1034    /// assert_eq!(a.into_ref::<String>()?.as_str(), "Hello World");
1035    /// assert_eq!(b.into_ref::<String>()?.as_str(), "Hello World");
1036    /// # Ok::<_, rune::support::Error>(())
1037    /// ```
1038    #[inline]
1039    pub fn into_ref<T>(self) -> Result<Ref<T>, RuntimeError>
1040    where
1041        T: Any,
1042    {
1043        match self.repr {
1044            Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1045            Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1046            Repr::Any(value) => Ok(value.into_ref()?),
1047        }
1048    }
1049
1050    /// Try to borrow value into a typed mutable reference of type `T`.
1051    #[inline]
1052    pub fn borrow_mut<T>(&self) -> Result<BorrowMut<'_, T>, RuntimeError>
1053    where
1054        T: Any,
1055    {
1056        match &self.repr {
1057            Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1058            Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1059            Repr::Any(value) => Ok(value.borrow_mut()?),
1060        }
1061    }
1062
1063    /// Try to coerce value into a typed mutable reference of type `T`.
1064    ///
1065    /// You should usually prefer to use [`rune::from_value`] instead of this
1066    /// directly since it supports transparently coercing into types like
1067    /// [`Mut<str>`].
1068    ///
1069    /// [`rune::from_value`]: crate::from_value
1070    ///
1071    /// # Examples
1072    ///
1073    /// ```
1074    /// use rune::{Mut, Value};
1075    /// use rune::alloc::String;
1076    ///
1077    /// let mut a = Value::try_from("Hello World")?;
1078    /// let b = a.clone();
1079    ///
1080    /// fn modify_string(mut s: Mut<String>) {
1081    ///     assert_eq!(s.as_str(), "Hello World");
1082    ///     s.make_ascii_lowercase();
1083    ///     assert_eq!(s.as_str(), "hello world");
1084    /// }
1085    ///
1086    /// modify_string(a.into_mut::<String>()?);
1087    ///
1088    /// assert_eq!(b.borrow_mut::<String>()?.as_str(), "hello world");
1089    /// # Ok::<_, rune::support::Error>(())
1090    /// ```
1091    #[inline]
1092    pub fn into_mut<T>(self) -> Result<Mut<T>, RuntimeError>
1093    where
1094        T: Any,
1095    {
1096        match self.repr {
1097            Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1098            Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1099            Repr::Any(value) => Ok(value.into_mut()?),
1100        }
1101    }
1102
1103    /// Get the type hash for the current value.
1104    ///
1105    /// One notable feature is that the type of a variant is its container
1106    /// *enum*, and not the type hash of the variant itself.
1107    #[inline(always)]
1108    pub fn type_hash(&self) -> Hash {
1109        match &self.repr {
1110            Repr::Inline(value) => value.type_hash(),
1111            Repr::Dynamic(value) => value.type_hash(),
1112            Repr::Any(value) => value.type_hash(),
1113        }
1114    }
1115
1116    /// Get the type information for the current value.
1117    #[inline(always)]
1118    pub fn type_info(&self) -> TypeInfo {
1119        match &self.repr {
1120            Repr::Inline(value) => value.type_info(),
1121            Repr::Dynamic(value) => value.type_info(),
1122            Repr::Any(value) => value.type_info(),
1123        }
1124    }
1125
1126    /// Perform a partial equality test between two values.
1127    ///
1128    /// This is the basis for the eq operation (`partial_eq` / '==').
1129    ///
1130    /// External types will use the [`Protocol::PARTIAL_EQ`] protocol when
1131    /// invoked through this function.
1132    ///
1133    /// # Errors
1134    ///
1135    /// This function will error if called outside of a virtual machine context.
1136    pub fn partial_eq(a: &Value, b: &Value) -> Result<bool, VmError> {
1137        Self::partial_eq_with(a, b, &mut EnvProtocolCaller)
1138    }
1139
1140    /// Perform a total equality test between two values.
1141    ///
1142    /// This is the basis for the eq operation (`partial_eq` / '==').
1143    #[cfg_attr(feature = "bench", inline(never))]
1144    pub(crate) fn partial_eq_with(
1145        &self,
1146        b: &Value,
1147        caller: &mut dyn ProtocolCaller,
1148    ) -> Result<bool, VmError> {
1149        self.bin_op_with(
1150            b,
1151            caller,
1152            &Protocol::PARTIAL_EQ,
1153            Inline::partial_eq,
1154            |lhs, rhs, caller| {
1155                if lhs.0.variant_hash != rhs.0.variant_hash {
1156                    return Ok(false);
1157                }
1158
1159                Vec::eq_with(lhs.1, rhs.1, Value::partial_eq_with, caller)
1160            },
1161        )
1162    }
1163
1164    /// Perform a total equality test between two values.
1165    ///
1166    /// This is the basis for the eq operation (`==`).
1167    ///
1168    /// External types will use the [`Protocol::EQ`] protocol when invoked
1169    /// through this function.
1170    ///
1171    /// # Errors
1172    ///
1173    /// This function will error if called outside of a virtual machine context.
1174    pub fn eq(&self, b: &Value) -> Result<bool, VmError> {
1175        self.eq_with(b, &mut EnvProtocolCaller)
1176    }
1177
1178    /// Perform a total equality test between two values.
1179    ///
1180    /// This is the basis for the eq operation (`==`).
1181    #[cfg_attr(feature = "bench", inline(never))]
1182    pub(crate) fn eq_with(
1183        &self,
1184        b: &Value,
1185        caller: &mut dyn ProtocolCaller,
1186    ) -> Result<bool, VmError> {
1187        self.bin_op_with(b, caller, &Protocol::EQ, Inline::eq, |lhs, rhs, caller| {
1188            if lhs.0.variant_hash != rhs.0.variant_hash {
1189                return Ok(false);
1190            }
1191
1192            Vec::eq_with(lhs.1, rhs.1, Value::eq_with, caller)
1193        })
1194    }
1195
1196    /// Perform a partial ordering comparison between two values.
1197    ///
1198    /// This is the basis for the comparison operation.
1199    ///
1200    /// External types will use the [`Protocol::PARTIAL_CMP`] protocol when
1201    /// invoked through this function.
1202    ///
1203    /// # Errors
1204    ///
1205    /// This function will error if called outside of a virtual machine context.
1206    pub fn partial_cmp(a: &Value, b: &Value) -> Result<Option<Ordering>, VmError> {
1207        Value::partial_cmp_with(a, b, &mut EnvProtocolCaller)
1208    }
1209
1210    /// Perform a partial ordering comparison between two values.
1211    ///
1212    /// This is the basis for the comparison operation.
1213    #[cfg_attr(feature = "bench", inline(never))]
1214    pub(crate) fn partial_cmp_with(
1215        &self,
1216        b: &Value,
1217        caller: &mut dyn ProtocolCaller,
1218    ) -> Result<Option<Ordering>, VmError> {
1219        self.bin_op_with(
1220            b,
1221            caller,
1222            &Protocol::PARTIAL_CMP,
1223            Inline::partial_cmp,
1224            |lhs, rhs, caller| {
1225                let ord = lhs.0.variant_hash.cmp(&rhs.0.variant_hash);
1226
1227                if ord != Ordering::Equal {
1228                    return Ok(Some(ord));
1229                }
1230
1231                Vec::partial_cmp_with(lhs.1, rhs.1, caller)
1232            },
1233        )
1234    }
1235
1236    /// Perform a total ordering comparison between two values.
1237    ///
1238    /// This is the basis for the comparison operation (`cmp`).
1239    ///
1240    /// External types will use the [`Protocol::CMP`] protocol when invoked
1241    /// through this function.
1242    ///
1243    /// # Errors
1244    ///
1245    /// This function will error if called outside of a virtual machine context.
1246    pub fn cmp(a: &Value, b: &Value) -> Result<Ordering, VmError> {
1247        Value::cmp_with(a, b, &mut EnvProtocolCaller)
1248    }
1249
1250    /// Perform a total ordering comparison between two values.
1251    ///
1252    /// This is the basis for the comparison operation (`cmp`).
1253    #[cfg_attr(feature = "bench", inline(never))]
1254    pub(crate) fn cmp_with(
1255        &self,
1256        b: &Value,
1257        caller: &mut dyn ProtocolCaller,
1258    ) -> Result<Ordering, VmError> {
1259        self.bin_op_with(
1260            b,
1261            caller,
1262            &Protocol::CMP,
1263            Inline::cmp,
1264            |lhs, rhs, caller| {
1265                let ord = lhs.0.variant_hash.cmp(&rhs.0.variant_hash);
1266
1267                if ord != Ordering::Equal {
1268                    return Ok(ord);
1269                }
1270
1271                Vec::cmp_with(lhs.1, rhs.1, caller)
1272            },
1273        )
1274    }
1275
1276    /// Hash the current value.
1277    pub fn hash(&self, hasher: &mut Hasher) -> Result<(), VmError> {
1278        self.hash_with(hasher, &mut EnvProtocolCaller)
1279    }
1280
1281    /// Hash the current value.
1282    #[cfg_attr(feature = "bench", inline(never))]
1283    pub(crate) fn hash_with(
1284        &self,
1285        hasher: &mut Hasher,
1286        caller: &mut dyn ProtocolCaller,
1287    ) -> Result<(), VmError> {
1288        match self.as_ref() {
1289            Repr::Inline(value) => {
1290                value.hash(hasher)?;
1291                return Ok(());
1292            }
1293            Repr::Any(value) => match value.type_hash() {
1294                Vec::HASH => {
1295                    let vec = value.borrow_ref::<Vec>()?;
1296                    return Vec::hash_with(&vec, hasher, caller);
1297                }
1298                OwnedTuple::HASH => {
1299                    let tuple = value.borrow_ref::<OwnedTuple>()?;
1300                    return Tuple::hash_with(&tuple, hasher, caller);
1301                }
1302                _ => {}
1303            },
1304            _ => {}
1305        }
1306
1307        let mut args = DynGuardedArgs::new((hasher,));
1308
1309        if let CallResultOnly::Ok(value) =
1310            caller.try_call_protocol_fn(&Protocol::HASH, self.clone(), &mut args)?
1311        {
1312            <()>::from_value(value)?;
1313            return Ok(());
1314        }
1315
1316        Err(VmError::new(VmErrorKind::UnsupportedUnaryOperation {
1317            op: Protocol::HASH.name,
1318            operand: self.type_info(),
1319        }))
1320    }
1321
1322    fn bin_op_with<T>(
1323        &self,
1324        b: &Value,
1325        caller: &mut dyn ProtocolCaller,
1326        protocol: &'static Protocol,
1327        inline: fn(&Inline, &Inline) -> Result<T, RuntimeError>,
1328        dynamic: fn(
1329            (&Arc<Rtti>, &[Value]),
1330            (&Arc<Rtti>, &[Value]),
1331            &mut dyn ProtocolCaller,
1332        ) -> Result<T, VmError>,
1333    ) -> Result<T, VmError>
1334    where
1335        T: FromValue,
1336    {
1337        match (self.as_ref(), b.as_ref()) {
1338            (Repr::Inline(lhs), Repr::Inline(rhs)) => return Ok(inline(lhs, rhs)?),
1339            (Repr::Inline(lhs), rhs) => {
1340                return Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1341                    op: protocol.name,
1342                    lhs: lhs.type_info(),
1343                    rhs: rhs.type_info(),
1344                }));
1345            }
1346            (Repr::Dynamic(lhs), Repr::Dynamic(rhs)) => {
1347                let lhs_rtti = lhs.rtti();
1348                let rhs_rtti = rhs.rtti();
1349
1350                let lhs = lhs.borrow_ref()?;
1351                let rhs = rhs.borrow_ref()?;
1352
1353                if lhs_rtti.hash == rhs_rtti.hash {
1354                    return dynamic((lhs_rtti, &lhs), (rhs_rtti, &rhs), caller);
1355                }
1356
1357                return Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1358                    op: protocol.name,
1359                    lhs: Rtti::type_info(lhs_rtti.clone()),
1360                    rhs: Rtti::type_info(rhs_rtti.clone()),
1361                }));
1362            }
1363            _ => {}
1364        }
1365
1366        if let CallResultOnly::Ok(value) =
1367            caller.try_call_protocol_fn(protocol, self.clone(), &mut Some((b.clone(),)))?
1368        {
1369            return Ok(T::from_value(value)?);
1370        }
1371
1372        Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1373            op: protocol.name,
1374            lhs: self.type_info(),
1375            rhs: b.type_info(),
1376        }))
1377    }
1378
1379    /// Try to coerce the current value as the specified integer `T`.
1380    ///
1381    /// # Examples
1382    ///
1383    /// ```
1384    /// let value = rune::to_value(u32::MAX)?;
1385    ///
1386    /// assert_eq!(value.as_integer::<u64>()?, u32::MAX as u64);
1387    /// assert!(value.as_integer::<i32>().is_err());
1388    ///
1389    /// # Ok::<(), rune::support::Error>(())
1390    /// ```
1391    pub fn as_integer<T>(&self) -> Result<T, RuntimeError>
1392    where
1393        T: TryFrom<u64> + TryFrom<i64>,
1394    {
1395        match self.repr {
1396            Repr::Inline(value) => value.as_integer(),
1397            Repr::Dynamic(ref value) => Err(RuntimeError::new(VmErrorKind::ExpectedNumber {
1398                actual: value.type_info(),
1399            })),
1400            Repr::Any(ref value) => Err(RuntimeError::new(VmErrorKind::ExpectedNumber {
1401                actual: value.type_info(),
1402            })),
1403        }
1404    }
1405
1406    pub(crate) fn as_inline_unchecked(&self) -> Option<&Inline> {
1407        match &self.repr {
1408            Repr::Inline(value) => Some(value),
1409            _ => None,
1410        }
1411    }
1412
1413    /// Test if the value is inline.
1414    pub(crate) fn is_inline(&self) -> bool {
1415        matches!(self.repr, Repr::Inline(..))
1416    }
1417
1418    /// Coerce into a checked [`Inline`] object.
1419    ///
1420    /// Any empty value will cause an access error.
1421    #[inline]
1422    pub(crate) fn as_inline(&self) -> Option<&Inline> {
1423        match &self.repr {
1424            Repr::Inline(value) => Some(value),
1425            Repr::Dynamic(..) => None,
1426            Repr::Any(..) => None,
1427        }
1428    }
1429
1430    #[inline]
1431    pub(crate) fn as_inline_mut(&mut self) -> Option<&mut Inline> {
1432        match &mut self.repr {
1433            Repr::Inline(value) => Some(value),
1434            Repr::Dynamic(..) => None,
1435            Repr::Any(..) => None,
1436        }
1437    }
1438
1439    /// Coerce into a checked [`AnyObj`] object.
1440    ///
1441    /// Any empty value will cause an access error.
1442    #[inline]
1443    pub fn as_any(&self) -> Option<&AnyObj> {
1444        match &self.repr {
1445            Repr::Inline(..) => None,
1446            Repr::Dynamic(..) => None,
1447            Repr::Any(value) => Some(value),
1448        }
1449    }
1450
1451    #[inline(always)]
1452    pub(crate) fn take_repr(self) -> Repr {
1453        self.repr
1454    }
1455
1456    #[inline(always)]
1457    pub(crate) fn as_ref(&self) -> &Repr {
1458        &self.repr
1459    }
1460
1461    #[inline(always)]
1462    pub(crate) fn as_mut(&mut self) -> &mut Repr {
1463        &mut self.repr
1464    }
1465
1466    #[inline]
1467    pub(crate) fn try_borrow_ref<T>(&self) -> Result<Option<BorrowRef<'_, T>>, AccessError>
1468    where
1469        T: Any,
1470    {
1471        match &self.repr {
1472            Repr::Inline(..) => Ok(None),
1473            Repr::Dynamic(..) => Ok(None),
1474            Repr::Any(value) => value.try_borrow_ref(),
1475        }
1476    }
1477
1478    #[inline]
1479    pub(crate) fn try_borrow_mut<T>(&self) -> Result<Option<BorrowMut<'_, T>>, AccessError>
1480    where
1481        T: Any,
1482    {
1483        match &self.repr {
1484            Repr::Inline(..) => Ok(None),
1485            Repr::Dynamic(..) => Ok(None),
1486            Repr::Any(value) => value.try_borrow_mut(),
1487        }
1488    }
1489
1490    pub(crate) fn protocol_into_iter(&self) -> Result<Value, VmError> {
1491        EnvProtocolCaller.call_protocol_fn(&Protocol::INTO_ITER, self.clone(), &mut ())
1492    }
1493
1494    pub(crate) fn protocol_next(&self) -> Result<Option<Value>, VmError> {
1495        let value = EnvProtocolCaller.call_protocol_fn(&Protocol::NEXT, self.clone(), &mut ())?;
1496
1497        Ok(FromValue::from_value(value)?)
1498    }
1499
1500    pub(crate) fn protocol_next_back(&self) -> Result<Option<Value>, VmError> {
1501        let value =
1502            EnvProtocolCaller.call_protocol_fn(&Protocol::NEXT_BACK, self.clone(), &mut ())?;
1503
1504        Ok(FromValue::from_value(value)?)
1505    }
1506
1507    pub(crate) fn protocol_nth_back(&self, n: usize) -> Result<Option<Value>, VmError> {
1508        let value = EnvProtocolCaller.call_protocol_fn(
1509            &Protocol::NTH_BACK,
1510            self.clone(),
1511            &mut Some((n,)),
1512        )?;
1513
1514        Ok(FromValue::from_value(value)?)
1515    }
1516
1517    pub(crate) fn protocol_len(&self) -> Result<usize, VmError> {
1518        let value = EnvProtocolCaller.call_protocol_fn(&Protocol::LEN, self.clone(), &mut ())?;
1519
1520        Ok(FromValue::from_value(value)?)
1521    }
1522
1523    pub(crate) fn protocol_size_hint(&self) -> Result<(usize, Option<usize>), VmError> {
1524        let value =
1525            EnvProtocolCaller.call_protocol_fn(&Protocol::SIZE_HINT, self.clone(), &mut ())?;
1526
1527        Ok(FromValue::from_value(value)?)
1528    }
1529}
1530
1531impl fmt::Debug for Value {
1532    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1533        match &self.repr {
1534            Repr::Inline(value) => {
1535                write!(f, "{value:?}")?;
1536            }
1537            _ => {
1538                let mut s = String::new();
1539                let result = Formatter::format_with(&mut s, |f| self.debug_fmt(f));
1540
1541                if let Err(e) = result {
1542                    match &self.repr {
1543                        Repr::Inline(value) => {
1544                            write!(f, "<{value:?}: {e}>")?;
1545                        }
1546                        Repr::Dynamic(value) => {
1547                            let ty = value.type_info();
1548                            write!(f, "<{ty} object at {value:p}: {e}>")?;
1549                        }
1550                        Repr::Any(value) => {
1551                            let ty = value.type_info();
1552                            write!(f, "<{ty} object at {value:p}: {e}>")?;
1553                        }
1554                    }
1555
1556                    return Ok(());
1557                }
1558
1559                f.write_str(s.as_str())?;
1560            }
1561        }
1562
1563        Ok(())
1564    }
1565}
1566
1567impl From<Repr> for Value {
1568    #[inline]
1569    fn from(repr: Repr) -> Self {
1570        Self { repr }
1571    }
1572}
1573
1574impl From<()> for Value {
1575    #[inline]
1576    fn from((): ()) -> Self {
1577        Value::from(Inline::Unit)
1578    }
1579}
1580
1581impl From<Inline> for Value {
1582    #[inline]
1583    fn from(value: Inline) -> Self {
1584        Self {
1585            repr: Repr::Inline(value),
1586        }
1587    }
1588}
1589
1590/// Conversion from a [`AnyObj`] into a [`Value`].
1591///
1592/// # Examples
1593///
1594/// ```
1595/// use rune::Value;
1596/// use rune::runtime::AnyObj;
1597/// use rune::alloc::String;
1598///
1599/// let string = String::try_from("Hello World")?;
1600/// let string = AnyObj::new(string)?;
1601/// let string = Value::from(string);
1602///
1603/// let string = string.into_shared::<String>()?;
1604/// assert_eq!(string.borrow_ref()?.as_str(), "Hello World");
1605/// # Ok::<_, rune::support::Error>(())
1606/// ```
1607impl From<AnyObj> for Value {
1608    #[inline]
1609    fn from(value: AnyObj) -> Self {
1610        Self {
1611            repr: Repr::Any(value),
1612        }
1613    }
1614}
1615
1616/// Conversion from a [`Shared<T>`] into a [`Value`].
1617///
1618/// # Examples
1619///
1620/// ```
1621/// use rune::Value;
1622/// use rune::runtime::Shared;
1623/// use rune::alloc::String;
1624///
1625/// let string = String::try_from("Hello World")?;
1626/// let string = Shared::new(string)?;
1627/// let string = Value::from(string);
1628///
1629/// let string = string.into_any_obj()?;
1630/// assert_eq!(string.borrow_ref::<String>()?.as_str(), "Hello World");
1631/// # Ok::<_, rune::support::Error>(())
1632/// ```
1633impl<T> From<Shared<T>> for Value
1634where
1635    T: Any,
1636{
1637    #[inline]
1638    fn from(value: Shared<T>) -> Self {
1639        Self {
1640            repr: Repr::Any(value.into_any_obj()),
1641        }
1642    }
1643}
1644
1645impl From<AnySequence<Arc<Rtti>, Value>> for Value {
1646    #[inline]
1647    fn from(value: AnySequence<Arc<Rtti>, Value>) -> Self {
1648        Self {
1649            repr: Repr::Dynamic(value),
1650        }
1651    }
1652}
1653
1654impl TryFrom<&str> for Value {
1655    type Error = alloc::Error;
1656
1657    #[inline]
1658    fn try_from(value: &str) -> Result<Self, Self::Error> {
1659        Value::new(String::try_from(value)?)
1660    }
1661}
1662
1663inline_from! {
1664    Bool => bool,
1665    Char => char,
1666    Signed => i64,
1667    Unsigned => u64,
1668    Float => f64,
1669    Type => Type,
1670    Ordering => Ordering,
1671    Hash => Hash,
1672}
1673
1674any_from! {
1675    crate::alloc::String,
1676    super::Bytes,
1677    super::Format,
1678    super::ControlFlow,
1679    super::GeneratorState,
1680    super::Vec,
1681    super::OwnedTuple,
1682    super::Generator,
1683    super::Stream,
1684    super::Function,
1685    super::Future,
1686    super::Object,
1687    Option<Value>,
1688    Result<Value, Value>,
1689}
1690
1691signed_value_from!(i8, i16, i32);
1692signed_value_try_from!(i128, isize);
1693unsigned_value_from!(u8, u16, u32);
1694unsigned_value_try_from!(u128, usize);
1695signed_value_trait!(i8, i16, i32, i128, isize);
1696unsigned_value_trait!(u8, u16, u32, u128, usize);
1697float_value_trait!(f32);
1698
1699impl MaybeTypeOf for Value {
1700    #[inline]
1701    fn maybe_type_of() -> alloc::Result<meta::DocType> {
1702        Ok(meta::DocType::empty())
1703    }
1704}
1705
1706impl Clone for Value {
1707    #[inline]
1708    fn clone(&self) -> Self {
1709        let repr = match &self.repr {
1710            Repr::Inline(inline) => Repr::Inline(*inline),
1711            Repr::Dynamic(mutable) => Repr::Dynamic(mutable.clone()),
1712            Repr::Any(any) => Repr::Any(any.clone()),
1713        };
1714
1715        Self { repr }
1716    }
1717
1718    #[inline]
1719    fn clone_from(&mut self, source: &Self) {
1720        match (&mut self.repr, &source.repr) {
1721            (Repr::Inline(lhs), Repr::Inline(rhs)) => {
1722                *lhs = *rhs;
1723            }
1724            (Repr::Dynamic(lhs), Repr::Dynamic(rhs)) => {
1725                lhs.clone_from(rhs);
1726            }
1727            (Repr::Any(lhs), Repr::Any(rhs)) => {
1728                lhs.clone_from(rhs);
1729            }
1730            (lhs, rhs) => {
1731                *lhs = rhs.clone();
1732            }
1733        }
1734    }
1735}
1736
1737impl TryClone for Value {
1738    fn try_clone(&self) -> alloc::Result<Self> {
1739        // NB: value cloning is a shallow clone of the underlying data.
1740        Ok(self.clone())
1741    }
1742}
1743
1744/// Wrapper for a value kind.
1745#[doc(hidden)]
1746pub struct NotTypedInline(Inline);
1747
1748/// Wrapper for an any ref value kind.
1749#[doc(hidden)]
1750pub struct NotTypedAnyObj<'a>(&'a AnyObj);
1751
1752/// The coersion of a value into a typed value.
1753#[non_exhaustive]
1754#[doc(hidden)]
1755pub enum TypeValue<'a> {
1756    /// The unit value.
1757    Unit,
1758    /// A tuple.
1759    Tuple(BorrowRef<'a, OwnedTuple>),
1760    /// An object.
1761    Object(BorrowRef<'a, Object>),
1762    /// An struct with a well-defined type.
1763    EmptyStruct(EmptyStruct<'a>),
1764    /// A tuple with a well-defined type.
1765    TupleStruct(TupleStruct<'a>),
1766    /// An struct with a well-defined type.
1767    Struct(Struct<'a>),
1768    /// Not a typed immutable value.
1769    #[doc(hidden)]
1770    NotTypedInline(NotTypedInline),
1771    /// Not a typed value.
1772    #[doc(hidden)]
1773    NotTypedAnyObj(NotTypedAnyObj<'a>),
1774}
1775
1776impl TypeValue<'_> {
1777    /// Get the type info of the current value.
1778    #[doc(hidden)]
1779    pub fn type_info(&self) -> TypeInfo {
1780        match self {
1781            TypeValue::Unit => TypeInfo::any::<OwnedTuple>(),
1782            TypeValue::Tuple(..) => TypeInfo::any::<OwnedTuple>(),
1783            TypeValue::Object(..) => TypeInfo::any::<Object>(),
1784            TypeValue::EmptyStruct(empty) => empty.type_info(),
1785            TypeValue::TupleStruct(tuple) => tuple.type_info(),
1786            TypeValue::Struct(object) => object.type_info(),
1787            TypeValue::NotTypedInline(value) => value.0.type_info(),
1788            TypeValue::NotTypedAnyObj(value) => value.0.type_info(),
1789        }
1790    }
1791}
1792
1793/// Ensures that `Value` and `Repr` is niche-filled when used in common
1794/// combinations.
1795#[test]
1796fn size_of_value() {
1797    use core::mem::size_of;
1798
1799    assert_eq!(size_of::<Repr>(), size_of::<Inline>());
1800    assert_eq!(size_of::<Repr>(), size_of::<Value>());
1801    assert_eq!(size_of::<Option<Value>>(), size_of::<Value>());
1802    assert_eq!(size_of::<Option<Repr>>(), size_of::<Repr>());
1803}