toasty_core/stmt/
input.rs1use crate::{
2 Schema,
3 stmt::{Expr, ExprArg, ExprContext, ExprReference, Project, Projection, Resolve, Type, Value},
4};
5
6pub trait Input {
23 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
28 let _ = (expr_arg, projection);
29 None
30 }
31
32 fn resolve_ref(
37 &mut self,
38 expr_reference: &ExprReference,
39 projection: &Projection,
40 ) -> Option<Expr> {
41 let _ = (expr_reference, projection);
42 None
43 }
44}
45
46#[derive(Debug, Default)]
61pub struct ConstInput {}
62
63pub struct TypedInput<'a, I, T = Schema> {
70 cx: ExprContext<'a, T>,
71 tys: &'a [Type],
72 input: I,
73}
74
75impl ConstInput {
76 pub fn new() -> ConstInput {
78 ConstInput {}
79 }
80}
81
82impl Input for ConstInput {}
83
84impl<'a, I, T> TypedInput<'a, I, T> {
85 pub fn new(cx: ExprContext<'a, T>, tys: &'a [Type], input: I) -> Self {
88 TypedInput { cx, tys, input }
89 }
90}
91
92impl<I: Input, T: Resolve> Input for TypedInput<'_, I, T> {
93 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
94 let expr = self.input.resolve_arg(expr_arg, projection)?;
95
96 if !expr.is_value_null() {
97 let actual_ty = self.cx.infer_expr_ty(&expr, &[]);
98
99 let mut ty = &self.tys[expr_arg.position];
100
101 for step in projection {
102 ty = match ty {
103 Type::Record(tys) => &tys[step],
104 Type::List(item) => item,
105 _ => todo!("ty={ty:#?}"),
106 };
107 }
108
109 assert!(
110 actual_ty.is_subtype_of(ty),
111 "resolved input did not match requested argument type; expected={ty:#?}; actual={actual_ty:#?}"
112 )
113 }
114
115 Some(expr)
116 }
117}
118
119impl Input for &Vec<Value> {
120 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
121 Some(self[expr_arg.position].entry(projection).to_expr())
122 }
123}
124
125impl<T, const N: usize> Input for [T; N]
126where
127 for<'a> &'a T: Project,
128{
129 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
130 (&self[expr_arg.position]).project(projection)
131 }
132}
133
134impl<T, const N: usize> Input for &[T; N]
135where
136 for<'a> &'a T: Project,
137{
138 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
139 (&self[expr_arg.position]).project(projection)
140 }
141}
142
143impl<T> Input for &[T]
144where
145 for<'a> &'a T: Project,
146{
147 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
148 (&self[expr_arg.position]).project(projection)
149 }
150}