runestick/
vec_tuple.rs

1use crate::{FromValue, ToValue, Value, VmError, VmErrorKind};
2
3/// A helper type to deserialize arrays with different interior types.
4///
5/// This implements [FromValue], allowing it to be used as a return value from
6/// a virtual machine.
7///
8/// [FromValue]: crate::FromValue
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct VecTuple<T>(pub T);
11
12impl<T> VecTuple<T>
13where
14    Self: ToValue,
15{
16    /// Construct a new vector tuple for serializing values.
17    pub fn new(inner: T) -> Self {
18        Self(inner)
19    }
20}
21
22macro_rules! impl_from_value_tuple_vec {
23    () => {
24    };
25
26    ({$ty:ident, $value:ident, $count:expr}, $({$rest_ty:ident, $rest_value:ident, $rest_count:expr},)*) => {
27        impl_from_value_tuple_vec!{@impl $count, {$ty, $value, $count}, $({$rest_ty, $rest_value, $rest_count},)*}
28        impl_from_value_tuple_vec!{$({$rest_ty, $rest_value, $rest_count},)*}
29    };
30
31    (@impl $count:expr, $({$ty:ident, $value:ident, $ignore_count:expr},)*) => {
32        impl<$($ty,)*> FromValue for VecTuple<($($ty,)*)>
33        where
34            $($ty: FromValue,)*
35        {
36            fn from_value(value: Value) -> Result<Self, VmError> {
37                let vec = value.into_vec()?;
38                let vec = vec.take()?;
39
40                if vec.len() != $count {
41                    return Err(VmError::from(VmErrorKind::ExpectedTupleLength {
42                        actual: vec.len(),
43                        expected: $count,
44                    }));
45                }
46
47                #[allow(unused_mut, unused_variables)]
48                let mut it = vec.into_iter();
49
50                $(
51                    let $value: $ty = match it.next() {
52                        Some(value) => <$ty>::from_value(value)?,
53                        None => {
54                            return Err(VmError::from(VmErrorKind::IterationError));
55                        },
56                    };
57                )*
58
59                Ok(VecTuple(($($value,)*)))
60            }
61        }
62
63        impl<$($ty,)*> ToValue for VecTuple<($($ty,)*)>
64        where
65            $($ty: ToValue,)*
66        {
67            fn to_value(self) -> Result<Value, VmError> {
68                let ($($value,)*) = self.0;
69                let vec = vec![$($value.to_value()?,)*];
70                Ok(Value::vec(vec))
71            }
72        }
73    };
74}
75
76repeat_macro!(impl_from_value_tuple_vec);