1#![allow(unused_mut)]
5#![allow(unused_parens)]
6#![allow(unused_variables)]
7
8use crate::*;
9use crate::runtime::*;
10use crate::{lang::{Varity, Parameter, Identifier}, stdlib::RantStdResult};
11use cast::*;
12use cast::Error as CastError;
13use std::{rc::Rc, ops::{DerefMut, Deref}, convert::TryInto};
14
15pub trait IntoRant: Sized {
17 fn into_rant(self) -> RantValue;
19}
20
21pub trait TryIntoRant: Sized {
23 fn try_into_rant(self) -> Result<RantValue, ValueError>;
25}
26
27pub trait FromRant: Sized {
28 fn from_rant(val: RantValue) -> Self;
30
31 fn is_optional_param_type() -> bool {
33 false
34 }
35}
36
37pub trait TryFromRant: Sized {
39 fn try_from_rant(val: RantValue) -> Result<Self, ValueError>;
41
42 fn is_optional_param_type() -> bool {
44 false
45 }
46}
47
48trait IntoCastResult<T> {
49 fn into_cast_result(self) -> Result<T, CastError>;
50}
51
52impl<T> IntoCastResult<T> for Result<T, CastError> {
53 fn into_cast_result(self) -> Result<T, CastError> {
54 self
55 }
56}
57
58impl IntoCastResult<i64> for i64 {
59 fn into_cast_result(self) -> Result<i64, CastError> {
60 Ok(self)
61 }
62}
63
64fn rant_cast_error(from: &'static str, to: &'static str, err: CastError) -> ValueError {
65 ValueError::InvalidConversion {
66 from,
67 to,
68 message: Some(match err {
69 CastError::Overflow => "integer overflow",
70 CastError::Underflow => "integer underflow",
71 CastError::Infinite => "infinity",
72 CastError::NaN => "NaN"
73 }.to_owned())
74 }
75}
76
77macro_rules! rant_fallible_int_conversions {
78 ($int_type: ident) => {
79 impl TryIntoRant for $int_type {
80 fn try_into_rant(self) -> ValueResult<RantValue> {
81 match i64(self).into_cast_result() {
82 Ok(i) => Ok(RantValue::Int(i)),
83 Err(err) => Err(rant_cast_error(
84 stringify!($int_type),
85 stringify!(RantValue::Int),
86 err
87 ))
88 }
89 }
90 }
91
92 impl TryFromRant for $int_type {
93 fn try_from_rant(val: RantValue) -> ValueResult<Self> {
94 macro_rules! cast_int {
95 (i64, $val:expr) => {
96 Ok($val)
97 };
98 (isize, $val:expr) => {
99 {
100 let val = $val;
101 val.try_into().map_err(|_| if val < 0 {
102 CastError::Underflow
103 } else {
104 CastError::Overflow
105 })
106 }
107 };
108 ($to:ident, $val:expr) => {
109 $to($val)
110 };
111 }
112 macro_rules! cast_float_to_int {
113 (i64, $val:expr) => {
114 Ok($val as i64)
115 };
116 ($to:ident, $val:expr) => {
117 $to($val)
118 };
119 }
120 match val {
121 RantValue::Int(i) => {
122 let result: Result<$int_type, CastError> = cast_int!($int_type, i);
123 match result {
124 Ok(i) => Ok(i),
125 Err(err) => Err(rant_cast_error(
126 val.type_name(),
127 stringify!($int_type),
128 err
129 ))
130 }
131 },
132 RantValue::Float(f) => {
133 let result: Result<$int_type, CastError> = cast_float_to_int!($int_type, f);
134 match result {
135 Ok(i) => Ok(i),
136 Err(err) => Err(rant_cast_error(
137 val.type_name(),
138 stringify!($int_type),
139 err
140 ))
141 }
142 },
143 _ => {
144 let src_type = val.type_name();
146 let dest_type = stringify!{$int_type};
147
148 Err(ValueError::InvalidConversion {
149 from: src_type,
150 to: dest_type,
151 message: None
152 })
153 }
154 }
155 }
156 }
157 };
158 ($int_type: ident, $($int_type2: ident), *) => {
159 rant_fallible_int_conversions! { $int_type }
160 rant_fallible_int_conversions! { $($int_type2), + }
161 };
162}
163
164macro_rules! converts_from_rant {
166 ($param:ident -> $t:ty $b:block) => {
167 impl FromRant for $t {
168 fn from_rant($param: RantValue) -> $t {
169 $b
170 }
171 }
172
173 impl TryFromRant for $t {
174 fn try_from_rant(val: RantValue) -> Result<$t, ValueError> {
175 Ok(<$t as FromRant>::from_rant(val))
176 }
177 }
178 }
179}
180
181macro_rules! converts_into_rant {
183 ($param:ident: $t:ty $b:block) => {
184 impl IntoRant for $t {
185 fn into_rant(self) -> RantValue {
186 let $param = self;
187 $b
188 }
189 }
190
191 impl TryIntoRant for $t {
192 fn try_into_rant(self) -> Result<RantValue, ValueError> {
193 Ok(IntoRant::into_rant(self))
194 }
195 }
196 }
197}
198
199rant_fallible_int_conversions! { u8, i8, u16, i16, u32, i32, u64, i64, isize, usize }
200
201converts_from_rant!(v -> RantNothing { Self });
202converts_from_rant!(v -> RantValue { v });
203converts_from_rant!(v -> bool { v.to_bool() });
204converts_from_rant!(v -> InternalString { v.to_string().into() });
205converts_from_rant!(v -> RantString { v.to_string().into() });
206converts_from_rant!(v -> String { v.to_string() });
207
208converts_into_rant!(v: RantValue { v });
209converts_into_rant!(v: RantNothing { RantValue::Nothing });
210converts_into_rant!(v: bool { RantValue::Boolean(v) });
211converts_into_rant!(v: char { RantValue::String(RantString::from(v)) });
212converts_into_rant!(v: f32 { RantValue::Float(v as f64) });
213converts_into_rant!(v: f64 { RantValue::Float(v) });
214converts_into_rant!(v: String { RantValue::String(v.into()) });
215converts_into_rant!(v: RantString { RantValue::String(v) });
216converts_into_rant!(v: InternalString { RantString::from(v.as_str()).into_rant() });
217converts_into_rant!(v: RantMap { RantValue::Map(v.into_handle()) });
218converts_into_rant!(v: RantMapHandle { RantValue::Map(v) });
219converts_into_rant!(v: RantList { RantValue::List(v.into_handle()) });
220converts_into_rant!(v: RantListHandle { RantValue::List(v) });
221converts_into_rant!(v: RantTuple { RantValue::Tuple(v.into_handle()) });
222converts_into_rant!(v: RantTupleHandle { RantValue::Tuple(v) });
223converts_into_rant!(v: RantSelector { RantValue::Selector(v.into_handle()) });
224converts_into_rant!(v: RantSelectorHandle { RantValue::Selector(v) });
225converts_into_rant!(v: RantRange { RantValue::Range(v) });
226
227impl<'a> IntoRant for &'a str {
228 fn into_rant(self) -> RantValue {
229 RantValue::String(self.into())
230 }
231}
232
233impl<'a> TryIntoRant for &'a str {
234 fn try_into_rant(self) -> Result<RantValue, ValueError> {
235 Ok(self.into_rant())
236 }
237}
238
239impl IntoRant for isize {
240 fn into_rant(self) -> RantValue {
241 RantValue::Int(self as i64)
242 }
243}
244
245impl IntoRant for i64 {
246 fn into_rant(self) -> RantValue {
247 RantValue::Int(self)
248 }
249}
250
251impl IntoRant for i32 {
252 fn into_rant(self) -> RantValue {
253 RantValue::Int(self as i64)
254 }
255}
256
257impl IntoRant for u32 {
258 fn into_rant(self) -> RantValue {
259 RantValue::Int(self as i64)
260 }
261}
262
263impl IntoRant for i16 {
264 fn into_rant(self) -> RantValue {
265 RantValue::Int(self as i64)
266 }
267}
268
269impl IntoRant for u16 {
270 fn into_rant(self) -> RantValue {
271 RantValue::Int(self as i64)
272 }
273}
274
275impl IntoRant for i8 {
276 fn into_rant(self) -> RantValue {
277 RantValue::Int(self as i64)
278 }
279}
280
281impl IntoRant for u8 {
282 fn into_rant(self) -> RantValue {
283 RantValue::Int(self as i64)
284 }
285}
286
287impl TryFromRant for f32 {
288 fn try_from_rant(val: RantValue) -> ValueResult<Self> {
289 match val {
290 RantValue::Int(i) => Ok(f32(i)),
291 RantValue::Float(f) => match f32(f) {
292 Ok(f) => Ok(f),
293 Err(err) => Err(rant_cast_error(val.type_name(), "f32", err))
294 },
295 _ => Err(ValueError::InvalidConversion {
296 from: val.type_name(),
297 to: "f32",
298 message: Some(format!("Rant value type '{}' cannot be converted to f32", val.type_name()))
299 })
300 }
301 }
302}
303
304impl TryFromRant for f64 {
305 fn try_from_rant(val: RantValue) -> ValueResult<Self> {
306 match val {
307 RantValue::Int(i) => Ok(f64(i)),
308 RantValue::Float(f) => Ok(f),
309 _ => Err(ValueError::InvalidConversion {
310 from: val.type_name(),
311 to: "f64",
312 message: Some(format!("Rant value type '{}' cannot be converted to f64", val.type_name()))
313 })
314 }
315 }
316}
317
318impl<T: IntoRant> IntoRant for Vec<T> {
319 fn into_rant(mut self) -> RantValue {
320 let list = self.drain(..).map(|v| v.into_rant()).collect::<RantList>();
321 RantValue::List(list.into_handle())
322 }
323}
324
325impl<T: TryIntoRant> TryIntoRant for Vec<T> {
326 fn try_into_rant(mut self) -> Result<RantValue, ValueError> {
327 let list = self.drain(..).map(|v| v.try_into_rant()).collect::<Result<RantList, ValueError>>()?;
328 Ok(list.into_rant())
329 }
330}
331
332impl TryFromRant for RantTupleHandle {
333 fn try_from_rant(val: RantValue) -> ValueResult<Self> {
334 if let RantValue::Tuple(tuple_ref) = val {
335 Ok(tuple_ref)
336 } else {
337 Err(ValueError::InvalidConversion { from: val.type_name(), to: RantValueType::Tuple.name(), message: None })
338 }
339 }
340}
341
342impl TryFromRant for RantListHandle {
343 fn try_from_rant(val: RantValue) -> ValueResult<Self> {
344 if let RantValue::List(list_ref) = val {
345 Ok(list_ref)
346 } else {
347 Err(ValueError::InvalidConversion { from: val.type_name(), to: RantValueType::List.name(), message: None })
348 }
349 }
350}
351
352impl TryFromRant for RantMapHandle {
353 fn try_from_rant(val: RantValue) -> ValueResult<Self> {
354 if let RantValue::Map(map_ref) = val {
355 Ok(map_ref)
356 } else {
357 Err(ValueError::InvalidConversion { from: val.type_name(), to: RantValueType::Map.name(), message: None })
358 }
359 }
360}
361
362impl TryFromRant for RantFunctionHandle {
363 fn try_from_rant(val: RantValue) -> Result<Self, ValueError> {
364 if let RantValue::Function(func_ref) = val {
365 Ok(func_ref)
366 } else {
367 Err(ValueError::InvalidConversion { from: val.type_name(), to: RantValueType::Function.name(), message: None })
368 }
369 }
370}
371
372impl TryFromRant for RantSelectorHandle {
373 fn try_from_rant(val: RantValue) -> Result<Self, ValueError> {
374 if let RantValue::Selector(sel_ref) = val {
375 Ok(sel_ref)
376 } else {
377 Err(ValueError::InvalidConversion { from: val.type_name(), to: RantValueType::Selector.name(), message: None })
378 }
379 }
380}
381
382impl<T: TryFromRant> TryFromRant for Option<T> {
383 fn try_from_rant(val: RantValue) -> ValueResult<Self> {
384 match val {
385 RantValue::Nothing => Ok(None),
386 other => Ok(Some(T::try_from_rant(other)?))
387 }
388 }
389 fn is_optional_param_type() -> bool {
390 true
391 }
392}
393
394impl<T: TryIntoRant> TryIntoRant for Option<T> {
395 fn try_into_rant(self) -> ValueResult<RantValue> {
396 match self {
397 Some(val) => Ok(val.try_into_rant()?),
398 None => Ok(RantValue::Nothing),
399 }
400 }
401}
402
403impl<T: IntoRant> IntoRant for Option<T> {
404 fn into_rant(self) -> RantValue {
405 match self {
406 Some(val) => val.into_rant(),
407 None => RantValue::Nothing,
408 }
409 }
410}
411
412impl<T: TryFromRant> TryFromRant for Vec<T> {
413 fn try_from_rant(val: RantValue) -> ValueResult<Self> {
414 match val {
415 RantValue::List(vec) => Ok(vec.borrow().iter().cloned().map(T::try_from_rant).collect::<ValueResult<Vec<T>>>()?),
416 other => Err(ValueError::InvalidConversion {
417 from: other.type_name(),
418 to: stringify!(Vec<T>),
419 message: Some("only lists can be turned into vectors".to_owned())
420 })
421 }
422 }
423}
424
425#[inline(always)]
426fn as_varity<T: TryFromRant>() -> Varity {
427 if T::is_optional_param_type() {
428 Varity::Optional
429 } else {
430 Varity::Required
431 }
432}
433
434#[inline(always)]
435fn inc(counter: &mut usize) -> usize {
436 let prev = *counter;
437 *counter += 1;
438 prev
439}
440
441pub trait FromRantArgs: Sized {
443 fn from_rant_args(args: Vec<RantValue>) -> ValueResult<Self>;
444 fn as_rant_params() -> Vec<Parameter>;
445}
446
447impl<T: TryFromRant> FromRantArgs for T {
448 fn from_rant_args(args: Vec<RantValue>) -> ValueResult<Self> {
449 let mut args = args.into_iter();
450 T::try_from_rant(args.next().unwrap_or(RantValue::Nothing))
451 }
452
453 fn as_rant_params() -> Vec<Parameter> {
454 let varity = if T::is_optional_param_type() {
455 Varity::Optional
456 } else {
457 Varity::Required
458 };
459
460 let param = Parameter {
461 name: Identifier::new(InternalString::from("arg0")),
462 varity,
463 default_value_expr: None,
464 };
465
466 vec![param]
467 }
468}
469
470pub struct VarArgs<T: TryFromRant>(Vec<T>);
474
475impl<T: TryFromRant> VarArgs<T> {
476 pub fn new(args: Vec<T>) -> Self {
477 Self(args)
478 }
479}
480
481impl<T: TryFromRant> Deref for VarArgs<T> {
482 type Target = Vec<T>;
483 fn deref(&self) -> &Self::Target {
484 &self.0
485 }
486}
487
488impl<T: TryFromRant> DerefMut for VarArgs<T> {
489 fn deref_mut(&mut self) -> &mut Self::Target {
490 &mut self.0
491 }
492}
493
494impl<T: TryFromRant> VarArgs<T> {
495 #[inline]
496 pub fn into_vec(self) -> Vec<T> {
497 self.0
498 }
499}
500
501pub struct RequiredVarArgs<T: TryFromRant>(Vec<T>);
505
506impl<T: TryFromRant> RequiredVarArgs<T> {
507 pub fn new(args: Vec<T>) -> Self {
508 Self(args)
509 }
510}
511
512impl<T: TryFromRant> Deref for RequiredVarArgs<T> {
513 type Target = Vec<T>;
514 fn deref(&self) -> &Self::Target {
515 &self.0
516 }
517}
518
519impl<T: TryFromRant> DerefMut for RequiredVarArgs<T> {
520 fn deref_mut(&mut self) -> &mut Self::Target {
521 &mut self.0
522 }
523}
524
525macro_rules! impl_from_rant_args {
526 ($($generic_types:ident),*) => {
527 impl<$($generic_types: TryFromRant,)*> FromRantArgs for ($($generic_types,)*) {
529 fn from_rant_args(args: Vec<RantValue>) -> ValueResult<Self> {
530 let mut args = args.into_iter();
531 Ok(($($generic_types::try_from_rant(args.next().unwrap_or(RantValue::Nothing))?,)*))
532 }
533
534 fn as_rant_params() -> Vec<Parameter> {
535 let mut i: usize = 0;
536 vec![$(Parameter {
537 name: Identifier::new(InternalString::from(format!("arg{}", inc(&mut i)))),
538 varity: as_varity::<$generic_types>(),
539 default_value_expr: None,
540 },)*]
541 }
542 }
543
544 impl<$($generic_types: TryFromRant,)* VarArgItem: TryFromRant> FromRantArgs for ($($generic_types,)* VarArgs<VarArgItem>) {
546 fn from_rant_args(mut args: Vec<RantValue>) -> ValueResult<Self> {
547 let mut args = args.drain(..);
548 Ok(
549 ($($generic_types::try_from_rant(args.next().unwrap_or(RantValue::Nothing))?,)*
550 VarArgs::new(args
551 .map(VarArgItem::try_from_rant)
552 .collect::<ValueResult<Vec<VarArgItem>>>()?
553 )
554 ))
555 }
556
557 fn as_rant_params() -> Vec<Parameter> {
558 let mut i: usize = 0;
559 vec![$(Parameter {
560 name: Identifier::new(InternalString::from(format!("arg{}", inc(&mut i)))),
561 varity: as_varity::<$generic_types>(),
562 default_value_expr: None,
563 },)*
564 Parameter {
565 name: Identifier::new(InternalString::from(format!("arg{}", inc(&mut i)))),
566 varity: Varity::VariadicStar,
567 default_value_expr: None,
568 }]
569 }
570 }
571
572 impl<$($generic_types: TryFromRant,)* VarArgItem: TryFromRant> FromRantArgs for ($($generic_types,)* RequiredVarArgs<VarArgItem>) {
574 fn from_rant_args(mut args: Vec<RantValue>) -> ValueResult<Self> {
575 let mut args = args.drain(..);
576 Ok(
577 ($($generic_types::try_from_rant(args.next().unwrap_or(RantValue::Nothing))?,)*
578 RequiredVarArgs::new(args
579 .map(VarArgItem::try_from_rant)
580 .collect::<ValueResult<Vec<VarArgItem>>>()?
581 )
582 ))
583 }
584
585 fn as_rant_params() -> Vec<Parameter> {
586 let mut i: usize = 0;
587 vec![$(Parameter {
588 name: Identifier::new(InternalString::from(format!("arg{}", inc(&mut i)))),
589 varity: as_varity::<$generic_types>(),
590 default_value_expr: None,
591 },)*
592 Parameter {
593 name: Identifier::new(InternalString::from(format!("arg{}", inc(&mut i)))),
594 varity: Varity::VariadicPlus,
595 default_value_expr: None,
596 }]
597 }
598 }
599 }
600}
601
602impl_from_rant_args!();
603impl_from_rant_args!(A);
604impl_from_rant_args!(A, B);
605impl_from_rant_args!(A, B, C);
606impl_from_rant_args!(A, B, C, D);
607impl_from_rant_args!(A, B, C, D, E);
608impl_from_rant_args!(A, B, C, D, E, F);
609impl_from_rant_args!(A, B, C, D, E, F, G);
610impl_from_rant_args!(A, B, C, D, E, F, G, H);
611impl_from_rant_args!(A, B, C, D, E, F, G, H, I);
612impl_from_rant_args!(A, B, C, D, E, F, G, H, I, J);
613impl_from_rant_args!(A, B, C, D, E, F, G, H, I, J, K);
614pub trait IntoRantFunction<Params: FromRantArgs> {
618 fn into_rant_func(self) -> RantFunction;
620}
621
622impl<Params: FromRantArgs, Function: 'static + Fn(&mut VM, Params) -> RantStdResult> IntoRantFunction<Params> for Function {
623 fn into_rant_func(self) -> RantFunction {
624 let body = RantFunctionInterface::Foreign(Rc::new(move |vm, args| {
625 self(vm, Params::from_rant_args(args).into_runtime_result()?)
626 }));
627
628 let params = Rc::new(Params::as_rant_params());
629
630 RantFunction {
631 body,
632 captured_vars: vec![],
633 min_arg_count: params.iter().take_while(|p| p.is_required()).count(),
634 vararg_start_index: params.iter()
635 .enumerate()
636 .find_map(|(i, p)| if p.varity.is_variadic() { Some(i) } else { None })
637 .unwrap_or_else(|| params.len()),
638 params,
639 flavor: None,
640 }
641 }
642}