rune/runtime/
into_output.rs

1use core::convert::Infallible;
2
3use crate::alloc;
4use crate::runtime::{AnySequence, Inline, Rtti, Value};
5use crate::sync::Arc;
6
7pub(crate) mod sealed {
8    use crate::runtime::{AnySequence, Inline, Rtti, Value};
9    use crate::sync::Arc;
10
11    use super::IntoOutput;
12
13    /// Sealed trait to prevent external implementations.
14    pub trait Sealed {}
15
16    impl<F, O> Sealed for F
17    where
18        F: FnOnce() -> O,
19        O: IntoOutput,
20    {
21    }
22
23    impl<T, E> Sealed for Result<T, E>
24    where
25        T: IntoOutput,
26        E: From<T::Error>,
27    {
28    }
29
30    impl Sealed for () {}
31    impl Sealed for Value {}
32    impl Sealed for Inline {}
33    impl Sealed for AnySequence<Arc<Rtti>, Value> {}
34    impl Sealed for &[u8] {}
35    impl Sealed for &str {}
36}
37
38/// Trait used to coerce values into outputs.
39pub trait IntoOutput: self::sealed::Sealed {
40    /// The error type produced by output coercion.
41    #[doc(hidden)]
42    type Error;
43
44    /// Coerce the current value into an output.
45    #[doc(hidden)]
46    fn into_output(self) -> Result<Value, Self::Error>;
47}
48
49impl<F, O> IntoOutput for F
50where
51    F: FnOnce() -> O,
52    O: IntoOutput,
53{
54    type Error = O::Error;
55
56    #[inline]
57    fn into_output(self) -> Result<Value, Self::Error> {
58        self().into_output()
59    }
60}
61
62impl<T, E> IntoOutput for Result<T, E>
63where
64    T: IntoOutput,
65    E: From<T::Error>,
66{
67    type Error = E;
68
69    #[inline]
70    fn into_output(self) -> Result<Value, Self::Error> {
71        Ok(self?.into_output()?)
72    }
73}
74
75impl IntoOutput for Value {
76    type Error = Infallible;
77
78    #[inline]
79    fn into_output(self) -> Result<Value, Self::Error> {
80        Ok(self)
81    }
82}
83
84impl IntoOutput for Inline {
85    type Error = Infallible;
86
87    #[inline]
88    fn into_output(self) -> Result<Value, Self::Error> {
89        Ok(Value::from(self))
90    }
91}
92
93impl IntoOutput for AnySequence<Arc<Rtti>, Value> {
94    type Error = Infallible;
95
96    #[inline]
97    fn into_output(self) -> Result<Value, Self::Error> {
98        Ok(Value::from(self))
99    }
100}
101
102impl IntoOutput for &[u8] {
103    type Error = alloc::Error;
104
105    #[inline]
106    fn into_output(self) -> Result<Value, Self::Error> {
107        Value::try_from(self)
108    }
109}
110
111impl IntoOutput for &str {
112    type Error = alloc::Error;
113
114    #[inline]
115    fn into_output(self) -> alloc::Result<Value> {
116        Value::try_from(self)
117    }
118}
119
120impl IntoOutput for () {
121    type Error = Infallible;
122
123    #[inline]
124    fn into_output(self) -> Result<Value, Self::Error> {
125        Ok(Value::from(()))
126    }
127}