kaon/common/
args.rs

1use crate::{common::value::ToValue, common::value::Value};
2
3use super::FromValue;
4
5pub type Result<T> = std::result::Result<T, String>;
6
7/// Represents a varidic arg type.
8///
9/// When used in rust functions, this must be the last parameter
10/// passed into the function.
11pub struct Varidic<T>(Vec<T>);
12
13impl<T: FromValue> Varidic<T> {
14    pub fn new_from_iter<V: FromValue>(iter: std::slice::Iter<'_, Value>) -> Self {
15        let mut v = Vec::<T>::new();
16
17        for i in iter.cloned() {
18            v.push(FromValue::from_value(i).unwrap());
19        }
20
21        Varidic(v)
22    }
23
24    pub fn iter(&self) -> std::slice::Iter<'_, T> {
25        self.0.iter()
26    }
27
28    pub fn len(&self) -> usize {
29        self.0.len()
30    }  
31}
32
33impl<T> From<Vec<T>> for Varidic<T> {
34    fn from(v: Vec<T>) -> Self {
35        Varidic(v)
36    }
37}
38
39impl<T: Clone> From<&[T]> for Varidic<T> {
40    fn from(v: &[T]) -> Self {
41        Varidic(v.to_vec())
42    }
43}
44
45impl<T: Clone> From<Box<[T]>> for Varidic<T> {
46    fn from(v: Box<[T]>) -> Self {
47        Varidic(v.to_vec())
48    }
49}
50
51impl<T: Clone> From<std::slice::Iter<'_, T>> for Varidic<T> {
52    fn from(iter: std::slice::Iter<'_, T>) -> Self {
53        let mut v = Vec::<T>::new();
54
55        for i in iter {
56            v.push(i.clone())
57        }
58
59        Varidic(v)
60    }
61}
62
63impl<T> IntoIterator for Varidic<T> {
64    type Item = T;
65    type IntoIter = std::vec::IntoIter<Self::Item>;
66
67    fn into_iter(self) -> Self::IntoIter {
68        self.0.into_iter()
69    }
70}
71
72macro_rules! impl_varidic_args {
73    ($num:literal) => {
74        impl<T: Clone> From<[T; $num]> for Varidic<T> {
75            fn from(v: [T; $num]) -> Self {
76                Self(v.to_vec())
77            }
78        }
79
80        impl<T: Clone> From<&[T; $num]> for Varidic<T> {
81            fn from(v: &[T; $num]) -> Self {
82                Self(v.to_vec())
83            }
84        }
85    };
86    ($num:literal $($nums:literal)*) => {
87        impl_varidic_args!($($nums)*);
88
89        impl<T: Clone> From<[T; $num]> for Varidic<T> {
90            fn from(v: [T; $num]) -> Self {
91                Self(v.to_vec())
92            }
93        }
94
95        impl<T: Clone> From<&[T; $num]> for Varidic<T> {
96            fn from(v: &[T; $num]) -> Self {
97                Self(v.to_vec())
98            }
99        }
100    };
101}
102
103impl_varidic_args!(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);
104
105/// A struct used to represent a function's arguments.
106#[derive(Debug, PartialEq)]
107pub struct Args(pub Vec<Value>);
108
109impl Args {
110    pub fn new() -> Self {
111        Args(Vec::new())
112    }
113
114    pub fn from_vec(values: Vec<Value>) -> Self {
115        Args(values)
116    }
117
118    pub fn push(&mut self, value: Value) {
119        self.0.push(value);
120    }
121}
122
123/// Trait for converting an arbitrary type into a vec of thrush values.
124pub trait ToArgs {
125    fn to_args(self) -> Result<Args>;
126}
127
128/// Trait for turning a vec of thrush values into some other type.
129pub trait FromArgs {
130    fn from_args(values: Args) -> Result<Self>
131    where
132        Self: Sized;
133}
134
135impl<T> ToArgs for T
136where
137    T: ToValue,
138{
139    fn to_args(self) -> Result<Args> {
140        Ok(Args::from_vec(vec![self.to_value()]))
141    }
142}
143
144impl ToArgs for Args {
145    fn to_args(self) -> Result<Args> {
146        Ok(self)
147    }
148}
149
150macro_rules! impl_tuple {
151    ($($name:ident)*) => {
152        impl<$($name,)*> ToArgs for ($($name,)*) where $($name: ToValue,)* {
153            #[allow(non_snake_case)]
154            fn to_args(self) -> Result<Args> {
155                let ($($name,)*) = self;
156
157                Ok(Args::from_vec(vec![$($name.to_value(),)*]))
158            }
159        }
160    };
161}
162
163impl_tuple!(A);
164impl_tuple!(A B);
165impl_tuple!(A B C);
166impl_tuple!(A B C D);
167impl_tuple!(A B C D E);
168impl_tuple!(A B C D E F);
169impl_tuple!(A B C D E F G);
170impl_tuple!(A B C D E F G H);
171impl_tuple!(A B C D E F G H I);
172impl_tuple!(A B C D E F G H I J);
173impl_tuple!(A B C D E F G H I J K);
174impl_tuple!(A B C D E F G H I J K L);
175impl_tuple!(A B C D E F G H I J K L M);
176impl_tuple!(A B C D E F G H I J K L M N);
177impl_tuple!(A B C D E F G H I J K L M N O);
178impl_tuple!(A B C D E F G H I J K L M N O P);
179
180#[cfg(test)]
181mod test {
182    use super::ToArgs;
183    use super::*;
184
185    #[test]
186    fn test_to_args() -> Result<()> {
187        assert_eq!((1f32).to_args()?, Args::from_vec(vec![Value::Float(1.0)]));
188        assert_eq!(
189            (1f32, "Hello").to_args()?,
190            Args::from_vec(vec![Value::Float(1.0), Value::String("Hello".into())])
191        );
192        assert_eq!(
193            (1f32, "Hello", true).to_args()?,
194            Args::from_vec(vec![
195                Value::Float(1.0),
196                Value::String("Hello".into()),
197                Value::TRUE
198            ])
199        );
200
201        Ok(())
202    }
203
204    #[test]
205    fn test_varidic_args() -> Result<()> {
206        fn test(args: Varidic<i32>) -> i32 {
207            let mut sum = 0;
208            for arg in args {
209                sum += arg;
210            }
211
212            sum
213        }
214
215        assert_eq!(15, test(Varidic::from([1, 2, 3, 4, 5])));
216        assert_eq!(15, test(Varidic::from(vec![1, 2, 3, 4, 5])));
217        assert_eq!(15, test(Varidic::from(vec![1, 2, 3, 4, 5].iter())));
218
219        Ok(())
220    }
221
222    #[test]
223    fn test() {
224        struct DefaultArg<T>(Option<T>);
225
226        impl<T: Clone> DefaultArg<T> {
227            fn or(&self, default: T) -> T {
228                if let Some(t) = &self.0 {
229                    t.clone()
230                } else {
231                    default
232                }
233            }
234        }
235
236        fn hello(x: DefaultArg<i32>, y: DefaultArg<i32>) -> i32 {
237            let x = x.or(30);
238            let y = y.or(2);
239
240            x + y
241        }
242
243        assert_eq!(8, hello(DefaultArg(Some(5)), DefaultArg(Some(3))));
244        assert_eq!(12, hello(DefaultArg(Some(10)), DefaultArg(None)));
245        assert_eq!(32, hello(DefaultArg(None), DefaultArg(None)));
246    }
247}