toasty_core/stmt/
input.rs1use crate::{
2 Schema,
3 schema::app::{Model, ModelId},
4 stmt::{Expr, ExprArg, ExprContext, ExprReference, Project, Projection, Resolve, Type, Value},
5};
6
7pub trait Input {
24 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
29 let _ = (expr_arg, projection);
30 None
31 }
32
33 fn resolve_ref(
38 &mut self,
39 expr_reference: &ExprReference,
40 projection: &Projection,
41 ) -> Option<Expr> {
42 let _ = (expr_reference, projection);
43 None
44 }
45
46 fn resolve_model(&self, id: ModelId) -> Option<&Model> {
54 let _ = id;
55 None
56 }
57}
58
59pub(crate) struct InputResolve<'a, I: ?Sized>(pub(crate) &'a I);
63
64impl<I: Input + ?Sized> Resolve for InputResolve<'_, I> {
65 fn model(&self, id: ModelId) -> Option<&Model> {
66 self.0.resolve_model(id)
67 }
68}
69
70#[derive(Debug, Default)]
85pub struct ConstInput {}
86
87pub struct TypedInput<'a, I, T = Schema> {
94 cx: ExprContext<'a, T>,
95 tys: &'a [Type],
96 input: I,
97}
98
99impl ConstInput {
100 pub fn new() -> ConstInput {
102 ConstInput {}
103 }
104}
105
106impl Input for ConstInput {}
107
108impl<'a, I, T> TypedInput<'a, I, T> {
109 pub fn new(cx: ExprContext<'a, T>, tys: &'a [Type], input: I) -> Self {
112 TypedInput { cx, tys, input }
113 }
114}
115
116impl<I: Input, T: Resolve> Input for TypedInput<'_, I, T> {
117 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
118 let expr = self.input.resolve_arg(expr_arg, projection)?;
119
120 let mut ty = &self.tys[expr_arg.position];
121
122 for step in projection {
123 ty = match ty {
124 Type::Record(tys) => &tys[step],
125 Type::List(item) => item,
126 _ => todo!("ty={ty:#?}"),
127 };
128 }
129
130 assert!(
131 expr.is_a(self.cx.schema(), ty),
132 "resolved input cannot evaluate to the requested argument type; expected={ty:#?}; actual={expr:#?}"
133 );
134
135 Some(expr)
136 }
137
138 fn resolve_model(&self, id: ModelId) -> Option<&Model> {
139 self.cx.schema().model(id)
140 }
141}
142
143impl Input for &Vec<Value> {
144 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
145 Some(self[expr_arg.position].entry(projection).to_expr())
146 }
147}
148
149impl<T, const N: usize> Input for [T; N]
150where
151 for<'a> &'a T: Project,
152{
153 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
154 (&self[expr_arg.position]).project(projection)
155 }
156}
157
158impl<T, const N: usize> Input for &[T; N]
159where
160 for<'a> &'a T: Project,
161{
162 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
163 (&self[expr_arg.position]).project(projection)
164 }
165}
166
167impl<T> Input for &[T]
168where
169 for<'a> &'a T: Project,
170{
171 fn resolve_arg(&mut self, expr_arg: &ExprArg, projection: &Projection) -> Option<Expr> {
172 (&self[expr_arg.position]).project(projection)
173 }
174}