@@ -13,7 +13,7 @@ use crate::compiler::{Compiler, DefaultCompiler};
1313use crate :: filter:: { CompiledExpr , CompiledValueExpr , Filter , FilterValue } ;
1414use crate :: lex:: { LexErrorKind , LexResult , LexWith } ;
1515use crate :: scheme:: { Scheme , UnknownFieldError } ;
16- use crate :: types:: { GetType , Type , TypeMismatchError } ;
16+ use crate :: types:: { GetType , LhsValue , Type , TypeMismatchError } ;
1717use serde:: Serialize ;
1818use std:: fmt:: { self , Debug } ;
1919
@@ -164,6 +164,75 @@ impl FilterAst {
164164 }
165165}
166166
167+ /// The root expression of a parsed value AST.
168+ #[ derive( PartialEq , Eq , Serialize , Clone , Hash ) ]
169+ #[ serde( untagged) ]
170+ pub enum FilterValueExpr {
171+ /// An indexed field or function-call expression.
172+ Index ( IndexExpr ) ,
173+ /// A logical expression that evaluates to a scalar boolean value.
174+ Logical ( LogicalExpr ) ,
175+ }
176+
177+ impl Debug for FilterValueExpr {
178+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
179+ match self {
180+ Self :: Index ( expr) => expr. fmt ( f) ,
181+ Self :: Logical ( expr) => expr. fmt ( f) ,
182+ }
183+ }
184+ }
185+
186+ impl < ' i , ' s > LexWith < ' i , & FilterParser < ' s > > for FilterValueExpr {
187+ fn lex_with ( input : & ' i str , parser : & FilterParser < ' s > ) -> LexResult < ' i , Self > {
188+ if let Some ( result) = LogicalExpr :: lex_quantifier_expr ( input, parser) {
189+ result. map ( |( expr, rest) | ( FilterValueExpr :: Logical ( expr) , rest) )
190+ } else {
191+ IndexExpr :: lex_with ( input, parser)
192+ . map ( |( expr, rest) | ( FilterValueExpr :: Index ( expr) , rest) )
193+ }
194+ }
195+ }
196+
197+ impl ValueExpr for FilterValueExpr {
198+ fn walk < ' a , V : Visitor < ' a > > ( & ' a self , visitor : & mut V ) {
199+ match self {
200+ Self :: Index ( expr) => visitor. visit_index_expr ( expr) ,
201+ Self :: Logical ( expr) => visitor. visit_logical_expr ( expr) ,
202+ }
203+ }
204+
205+ fn walk_mut < ' a , V : VisitorMut < ' a > > ( & ' a mut self , visitor : & mut V ) {
206+ match self {
207+ Self :: Index ( expr) => visitor. visit_index_expr ( expr) ,
208+ Self :: Logical ( expr) => visitor. visit_logical_expr ( expr) ,
209+ }
210+ }
211+
212+ fn compile_with_compiler < C : Compiler > ( self , compiler : & mut C ) -> CompiledValueExpr < C :: U > {
213+ match self {
214+ Self :: Index ( expr) => compiler. compile_index_expr ( expr) ,
215+ Self :: Logical ( expr) => match compiler. compile_logical_expr ( expr) {
216+ CompiledExpr :: One ( expr) => {
217+ CompiledValueExpr :: new ( move |ctx| LhsValue :: from ( expr. execute ( ctx) ) . into ( ) )
218+ }
219+ CompiledExpr :: Vec ( expr) => CompiledValueExpr :: new ( move |ctx| {
220+ LhsValue :: Array ( expr. execute ( ctx) . into ( ) ) . into ( )
221+ } ) ,
222+ } ,
223+ }
224+ }
225+ }
226+
227+ impl GetType for FilterValueExpr {
228+ fn get_type ( & self ) -> Type {
229+ match self {
230+ Self :: Index ( expr) => expr. get_type ( ) ,
231+ Self :: Logical ( expr) => expr. get_type ( ) ,
232+ }
233+ }
234+ }
235+
167236/// A parsed value AST.
168237///
169238/// It's attached to its corresponding [`Scheme`](struct@Scheme) because all
@@ -175,7 +244,7 @@ pub struct FilterValueAst {
175244 #[ serde( skip) ]
176245 scheme : Scheme ,
177246
178- op : IndexExpr ,
247+ op : FilterValueExpr ,
179248}
180249
181250impl Debug for FilterValueAst {
@@ -186,12 +255,14 @@ impl Debug for FilterValueAst {
186255
187256impl < ' i , ' s > LexWith < ' i , & FilterParser < ' s > > for FilterValueAst {
188257 fn lex_with ( input : & ' i str , parser : & FilterParser < ' s > ) -> LexResult < ' i , Self > {
189- let ( op, rest) = IndexExpr :: lex_with ( input. trim ( ) , parser) ?;
190- if op. map_each_count ( ) > 0 {
258+ let ( op, rest) = FilterValueExpr :: lex_with ( input. trim ( ) , parser) ?;
259+ if let FilterValueExpr :: Index ( expr) = & op
260+ && expr. map_each_count ( ) > 0
261+ {
191262 Err ( (
192263 LexErrorKind :: TypeMismatch ( TypeMismatchError {
193- expected : op . get_type ( ) . into ( ) ,
194- actual : Type :: Array ( op . get_type ( ) . into ( ) ) ,
264+ expected : expr . get_type ( ) . into ( ) ,
265+ actual : Type :: Array ( expr . get_type ( ) . into ( ) ) ,
195266 } ) ,
196267 input,
197268 ) )
@@ -216,20 +287,20 @@ impl FilterValueAst {
216287
217288 /// Returns the associated expression.
218289 #[ inline]
219- pub fn expression ( & self ) -> & IndexExpr {
290+ pub fn expression ( & self ) -> & FilterValueExpr {
220291 & self . op
221292 }
222293
223294 /// Recursively visit all nodes in the AST using a [`Visitor`].
224295 #[ inline]
225296 pub fn walk < ' a , V : Visitor < ' a > > ( & ' a self , visitor : & mut V ) {
226- visitor. visit_index_expr ( & self . op )
297+ visitor. visit_value_expr ( & self . op )
227298 }
228299
229300 /// Recursively visit all nodes in the AST using a [`VisitorMut`].
230301 #[ inline]
231302 pub fn walk_mut < ' a , V : VisitorMut < ' a > > ( & ' a mut self , visitor : & mut V ) {
232- visitor. visit_index_expr ( & mut self . op )
303+ visitor. visit_value_expr ( & mut self . op )
233304 }
234305
235306 /// Recursively checks whether a [`FilterAst`] uses a given field name.
@@ -254,7 +325,7 @@ impl FilterValueAst {
254325
255326 /// Compiles a [`FilterValueAst`] into a [`FilterValue`] using a specific [`Compiler`].
256327 pub fn compile_with_compiler < C : Compiler > ( self , compiler : & mut C ) -> FilterValue < C :: U > {
257- FilterValue :: new ( compiler. compile_index_expr ( self . op ) , self . scheme )
328+ FilterValue :: new ( compiler. compile_value_expr ( self . op ) , self . scheme )
258329 }
259330
260331 /// Compiles a [`FilterValueAst`] into a [`FilterValue`] using the [`DefaultCompiler`].
0 commit comments