1use crate::ConditionInstance;
4use crate::TestDsl;
5use crate::VerbInstance;
6use crate::error;
7use crate::error::TestErrorCase;
8
9pub trait ParseArguments<H>: std::fmt::Debug + Clone + Sized + 'static {
13 fn parse(test_dsl: &TestDsl<H>, node: &kdl::KdlNode) -> Result<Self, TestErrorCase>;
18}
19
20pub(crate) trait BoxedArguments<H>: std::fmt::Debug + std::any::Any {
21 fn clone_box(&self) -> Box<dyn BoxedArguments<H>>;
22 fn as_dyn_any(&self) -> &dyn std::any::Any;
23}
24
25impl<H: 'static> Clone for Box<dyn BoxedArguments<H>> {
26 fn clone(&self) -> Self {
27 (**self).clone_box()
28 }
29}
30
31impl<H, A: ParseArguments<H>> BoxedArguments<H> for A {
32 fn clone_box(&self) -> Box<dyn BoxedArguments<H>> {
33 Box::new(self.clone())
34 }
35
36 fn as_dyn_any(&self) -> &dyn std::any::Any {
37 self
38 }
39}
40
41impl<H> ParseArguments<H> for ((),) {
42 fn parse(_test_dsl: &TestDsl<H>, _node: &kdl::KdlNode) -> Result<Self, TestErrorCase> {
43 Ok(((),))
44 }
45}
46
47macro_rules! impl_parse_arguments {
48 (
49 [$($ty:ident),*], $last:ident
50 ) => {
51 #[allow(non_snake_case, unused_mut)]
52 impl<H, $($ty,)* $last> ParseArguments<H> for ($($ty,)* $last,)
53 where
54 $( $ty: VerbArgument + 'static , )*
55 $last: VerbArgument + 'static,
56 ($($ty,)* $last,): std::fmt::Debug,
57 {
58 fn parse(_test_dsl: &TestDsl<H>, node: &kdl::KdlNode) -> Result<Self, TestErrorCase> {
59 let mut args = node.iter();
60
61 let total_count = 1
62 $(
63 + {
64 const _: () = {
65 #[allow(unused)]
66 let $ty = ();
67 };
68 1
69 }
70
71 )*;
72
73 let mut running_count = 1;
74
75 $(
76 let arg = args.next().ok_or_else(|| TestErrorCase::MissingArgument {
77 parent: node.span(),
78 missing: format!("This verb takes {} arguments, you're missing the {}th argument.", total_count, running_count),
79 })?;
80
81 let $ty = <$ty as VerbArgument>::from_value(arg).ok_or_else(|| {
82 TestErrorCase::WrongArgumentType {
83 parent: node.name().span(),
84 argument: arg.span(),
85 expected: format!("This verb takes a '{}' as its argument here.", <$ty as VerbArgument>::get_error_type_name()),
86 }
87 })?;
88 running_count += 1;
89 )*
90
91 let _ = running_count;
92
93 let arg = args.next().ok_or_else(|| TestErrorCase::MissingArgument {
94 parent: node.span(),
95 missing: format!("This verb takes {tc} arguments, you're missing the {tc}th argument.", tc = total_count),
96 })?;
97 let $last = <$last as VerbArgument>::from_value(arg).ok_or_else(|| {
98 TestErrorCase::WrongArgumentType {
99 parent: node.name().span(),
100 argument: arg.span(),
101 expected: format!("This verb takes a '{}' as its argument here.", <$last as VerbArgument>::get_error_type_name()),
102 }
103 })?;
104
105
106 Ok(($($ty,)* $last,))
107 }
108 }
109 };
110}
111
112all_the_tuples!(impl_parse_arguments);
113
114pub trait VerbArgument: Clone {
116 fn get_error_type_name() -> &'static str {
120 std::any::type_name::<Self>()
121 }
122
123 fn from_value(value: &kdl::KdlEntry) -> Option<Self>;
128}
129
130impl VerbArgument for String {
131 fn from_value(value: &kdl::KdlEntry) -> Option<Self> {
132 value.value().as_string().map(ToOwned::to_owned)
133 }
134}
135
136impl VerbArgument for usize {
137 fn from_value(value: &kdl::KdlEntry) -> Option<Self> {
138 value.value().as_integer().map(|i| i as usize)
139 }
140}
141
142impl VerbArgument for f64 {
143 fn from_value(value: &kdl::KdlEntry) -> Option<Self> {
144 value.value().as_float()
145 }
146}
147
148impl VerbArgument for bool {
149 fn from_value(value: &kdl::KdlEntry) -> Option<Self> {
150 value.value().as_bool()
151 }
152}
153
154pub struct ConditionChildren<H, A> {
156 parameters: A,
157 children: Vec<ConditionInstance<H>>,
158}
159
160impl<H, A: std::fmt::Debug> std::fmt::Debug for ConditionChildren<H, A> {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 f.debug_struct("ConditionChildren")
163 .field("parameters", &self.parameters)
164 .field("children", &self.children)
165 .finish()
166 }
167}
168
169impl<H: 'static, A: Clone> Clone for ConditionChildren<H, A> {
170 fn clone(&self) -> Self {
171 Self {
172 parameters: self.parameters.clone(),
173 children: self.children.clone(),
174 }
175 }
176}
177
178impl<H, A> ConditionChildren<H, A> {
179 pub fn parameters(&self) -> &A {
181 &self.parameters
182 }
183
184 pub fn children(&self) -> &[ConditionInstance<H>] {
186 &self.children
187 }
188}
189
190impl<H: 'static, A: ParseArguments<H>> ParseArguments<H> for ConditionChildren<H, A> {
191 fn parse(test_dsl: &TestDsl<H>, node: &kdl::KdlNode) -> Result<Self, error::TestErrorCase> {
192 let arguments = A::parse(test_dsl, node)?;
193
194 let children = node
195 .iter_children()
196 .map(|node| ConditionInstance::with_test_dsl(test_dsl, node))
197 .collect::<Result<_, _>>()?;
198
199 Ok(ConditionChildren {
200 parameters: arguments,
201 children,
202 })
203 }
204}
205
206pub struct VerbChildren<H, A> {
208 parameters: A,
209 children: Vec<VerbInstance<H>>,
210}
211
212impl<H, A: std::fmt::Debug> std::fmt::Debug for VerbChildren<H, A> {
213 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
214 f.debug_struct("VerbChildren")
215 .field("parameters", &self.parameters)
216 .field("children", &self.children)
217 .finish()
218 }
219}
220
221impl<H: 'static, A: Clone> Clone for VerbChildren<H, A> {
222 fn clone(&self) -> Self {
223 Self {
224 parameters: self.parameters.clone(),
225 children: self.children.clone(),
226 }
227 }
228}
229
230impl<H, A> VerbChildren<H, A> {
231 pub fn parameters(&self) -> &A {
233 &self.parameters
234 }
235
236 pub fn children(&self) -> &[VerbInstance<H>] {
238 &self.children
239 }
240}
241
242impl<H: 'static, A: ParseArguments<H>> ParseArguments<H> for VerbChildren<H, A> {
243 fn parse(test_dsl: &TestDsl<H>, node: &kdl::KdlNode) -> Result<Self, error::TestErrorCase> {
244 let arguments = A::parse(test_dsl, node)?;
245
246 let children = node
247 .iter_children()
248 .map(|node| VerbInstance::with_test_dsl(test_dsl, node))
249 .collect::<Result<_, _>>()?;
250
251 Ok(VerbChildren {
252 parameters: arguments,
253 children,
254 })
255 }
256}