soroban_env_common/
tuple.rs

1use crate::{Env, TryFromVal, TryIntoVal, Val, VecObject};
2
3macro_rules! impl_for_tuple {
4    ( $count:literal $count_usize:literal $($typ:ident $idx:tt)+ ) => {
5
6        // Conversions to and from Val.
7
8        impl<E: Env, $($typ),*> TryFromVal<E, Val> for ($($typ,)*)
9        where
10            $($typ: TryFromVal<E, Val>),*
11        {
12            type Error = crate::Error;
13
14            fn try_from_val(env: &E, val: &Val) -> Result<Self, Self::Error> {
15                let vec: VecObject = val.try_into()?;
16                let mut tmp: [Val; $count as usize] = [Val::VOID.to_val(); $count as usize];
17                env.vec_unpack_to_slice(vec, &mut tmp).map_err(Into::into)?;
18                Ok(($($typ::try_from_val(env, &tmp[$idx]).map_err(Into::into)?,)*))
19            }
20        }
21
22        impl<E: Env, $($typ),*> TryFromVal<E, ($($typ,)*)> for Val
23        where
24            $($typ: TryIntoVal<E, Val>),*
25        {
26            type Error = crate::Error;
27            fn try_from_val(env: &E, v: &($($typ,)*)) -> Result<Self, Self::Error> {
28                let tmp: [Val; $count as usize] = [
29                    $(v.$idx.try_into_val(&env).map_err(Into::into)?,)*
30                ];
31                let vec = env.vec_new_from_slice(&tmp).map_err(Into::into)?;
32                Ok(vec.to_val())
33            }
34        }
35
36        impl<E: Env, $($typ),*> TryFromVal<E, &($($typ,)*)> for Val
37        where
38            $($typ: TryIntoVal<E, Val>),*
39        {
40            type Error = crate::Error;
41            fn try_from_val(env: &E, v: &&($($typ,)*)) -> Result<Self, Self::Error> {
42                Self::try_from_val(env, *v)
43            }
44        }
45
46
47        // Conversions to and from Array of Val.
48
49        impl<E: Env, $($typ),*, const N: usize> TryFromVal<E, [Val; N]> for ($($typ,)*)
50        where
51            $($typ: TryFromVal<E, Val>),*
52        {
53            type Error = crate::Error;
54
55            fn try_from_val(env: &E, val: &[Val; N]) -> Result<Self, Self::Error> {
56                Ok((
57                    $({
58                        $typ::try_from_val(&env, &val[$idx]).map_err(Into::into)?
59                    },)*
60                ))
61            }
62        }
63
64        impl<E: Env, $($typ),*, const N: usize> TryFromVal<E, ($($typ,)*)> for [Val; N]
65        where
66            $(Val: TryFromVal<E, $typ>),*
67        {
68            type Error = crate::Error;
69
70            fn try_from_val(env: &E, val: &($($typ,)*)) -> Result<Self, Self::Error> {
71                let mut arr: [Val; N] = [Val::VOID.into(); N];
72                $(arr[$idx] = val.$idx.try_into_val(env).map_err(Into::into)?;)*
73                Ok(arr)
74            }
75        }
76    };
77}
78
79impl_for_tuple! {  1_u32  1_usize T0 0 }
80impl_for_tuple! {  2_u32  2_usize T0 0 T1 1 }
81impl_for_tuple! {  3_u32  3_usize T0 0 T1 1 T2 2 }
82impl_for_tuple! {  4_u32  4_usize T0 0 T1 1 T2 2 T3 3 }
83impl_for_tuple! {  5_u32  5_usize T0 0 T1 1 T2 2 T3 3 T4 4 }
84impl_for_tuple! {  6_u32  6_usize T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 }
85impl_for_tuple! {  7_u32  7_usize T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 }
86impl_for_tuple! {  8_u32  8_usize T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 }
87impl_for_tuple! {  9_u32  9_usize T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 }
88impl_for_tuple! { 10_u32 10_usize T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 }
89impl_for_tuple! { 11_u32 11_usize T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 }
90impl_for_tuple! { 12_u32 12_usize T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 }
91impl_for_tuple! { 13_u32 13_usize T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 }
92
93// Unit types are not tuples, but when people write out what they think is an
94// empty tuple, it is a unit type. The following conversions on unit types
95// behave like tuples in some conversions that are safe to do so, like
96// conversions to and from arrays. Note that unit types directly convert to
97// Val::VOID, see val.rs for those conversions.
98
99impl<E: Env> TryFromVal<E, [Val; 0]> for () {
100    type Error = crate::Error;
101
102    fn try_from_val(_env: &E, _val: &[Val; 0]) -> Result<Self, Self::Error> {
103        Ok(())
104    }
105}
106
107impl<E: Env> TryFromVal<E, ()> for [Val; 0] {
108    type Error = crate::Error;
109
110    fn try_from_val(_env: &E, _v: &()) -> Result<Self, Self::Error> {
111        Ok([])
112    }
113}