toasty_core/stmt/
input.rs1use crate::{
2 stmt::{Expr, ExprArg, ExprContext, ExprReference, Project, Projection, Resolve, Type, Value},
3 Schema,
4};
5
6pub trait Input {
7 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
8 let _ = (expr_arg, projection);
9 None
10 }
11
12 fn resolve_ref(
13 &mut self,
14 expr_reference: &ExprReference,
15 projection: &Projection,
16 ) -> Option<Expr> {
17 let _ = (expr_reference, projection);
18 None
19 }
20}
21
22#[derive(Debug, Default)]
23pub struct ConstInput {}
24
25pub struct TypedInput<'a, I, T = Schema> {
26 cx: ExprContext<'a, T>,
27 tys: &'a [Type],
28 input: I,
29}
30
31impl ConstInput {
32 pub fn new() -> ConstInput {
33 ConstInput {}
34 }
35}
36
37impl Input for ConstInput {}
38
39impl<'a, I, T> TypedInput<'a, I, T> {
40 pub fn new(cx: ExprContext<'a, T>, tys: &'a [Type], input: I) -> Self {
41 TypedInput { cx, tys, input }
42 }
43}
44
45impl<I: Input, T: Resolve> Input for TypedInput<'_, I, T> {
46 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
47 let expr = self.input.resolve_arg(expr_arg, projection)?;
48
49 if !expr.is_value_null() {
50 let actual_ty = self.cx.infer_expr_ty(&expr, &[]);
51
52 let mut ty = &self.tys[expr_arg.position];
53
54 for step in projection {
55 ty = match ty {
56 Type::Record(tys) => &tys[step],
57 Type::List(item) => item,
58 _ => todo!("ty={ty:#?}"),
59 };
60 }
61
62 assert!(actual_ty.is_subtype_of(ty), "resolved input did not match requested argument type; expected={ty:#?}; actual={actual_ty:#?}")
63 }
64
65 Some(expr)
66 }
67}
68
69impl Input for &Vec<Value> {
70 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
71 Some(self[expr_arg.position].entry(projection).to_expr())
72 }
73}
74
75impl<T, const N: usize> Input for [T; N]
76where
77 for<'a> &'a T: Project,
78{
79 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
80 (&self[expr_arg.position]).project(projection)
81 }
82}
83
84impl<T, const N: usize> Input for &[T; N]
85where
86 for<'a> &'a T: Project,
87{
88 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
89 (&self[expr_arg.position]).project(projection)
90 }
91}
92
93impl<T> Input for &[T]
94where
95 for<'a> &'a T: Project,
96{
97 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
98 (&self[expr_arg.position]).project(projection)
99 }
100}