@@ -102,6 +102,16 @@ impl<'src> FuncContext<'src> {
102102 Ok ( constructor ( self . get ( 0 ) ?) )
103103 }
104104
105+ fn args2 < Arg1 , Arg2 > (
106+ & mut self ,
107+ constructor : impl FnOnce ( Arg1 , Arg2 ) -> Expr ,
108+ ) -> Result < Expr , Rich < ' src , char > >
109+ where
110+ Self : GetArg < ' src , Arg1 > + GetArg < ' src , Arg2 > ,
111+ {
112+ Ok ( constructor ( self . get ( 0 ) ?, self . get ( 1 ) ?) )
113+ }
114+
105115 fn unknown ( & self ) -> Result < Expr , Rich < ' src , char > > {
106116 Err ( Rich :: custom (
107117 self . func_name_span ,
@@ -147,28 +157,27 @@ trait GetArg<'src, T> {
147157 fn get ( & mut self , index : usize ) -> Result < T , Rich < ' src , char > > ;
148158}
149159
150- impl < ' src > GetArg < ' src , String > for FuncContext < ' src > {
151- fn get ( & mut self , index : usize ) -> Result < String , Rich < ' src , char > > {
152- let arg = self . get_arg ( index) ?;
153- if let FuncArgument :: Expression ( Expr :: Literal ( ExprValue :: String ( value) ) ) = arg. 0 {
154- Ok ( value)
155- } else {
156- Err ( self . arg_type_err ( arg. 1 , arg. 2 , index, "String" ) )
160+ macro_rules! impl_get_arg {
161+ ( $ty: ty, $pat: pat => $val: expr, $expected: literal) => {
162+ impl <' src> GetArg <' src, $ty> for FuncContext <' src> {
163+ fn get( & mut self , index: usize ) -> Result <$ty, Rich <' src, char >> {
164+ let arg = self . get_arg( index) ?;
165+ Ok ( match arg. 0 {
166+ $pat => $val,
167+ _ => return Err ( self . arg_type_err( arg. 1 , arg. 2 , index, $expected) ) ,
168+ } )
169+ }
157170 }
158- }
171+ } ;
159172}
160173
161- impl < ' src > GetArg < ' src , Vec < Expr > > for FuncContext < ' src > {
162- fn get ( & mut self , index : usize ) -> Result < Vec < Expr > , Rich < ' src , char > > {
163- let arg = self . get_arg ( index) ?;
164- if let FuncArgument :: Array ( arr) = arg. 0 {
165- Ok ( arr)
166- } else {
167- dbg ! ( & arg. 0 ) ;
168- Err ( self . arg_type_err ( arg. 1 , arg. 2 , index, "[Array]" ) )
169- }
170- }
171- }
174+ impl_get_arg ! ( Box <Expr >, FuncArgument :: Expression ( v) => Box :: new( v) , "Expression" ) ;
175+ impl_get_arg ! (
176+ String ,
177+ FuncArgument :: Expression ( Expr :: Literal ( ExprValue :: String ( v) ) ) => v,
178+ "String"
179+ ) ;
180+ impl_get_arg ! ( Vec <Expr >, FuncArgument :: Array ( v) => v, "[Array]" ) ;
172181
173182#[ derive( Debug ) ]
174183enum FuncArgument {
@@ -220,8 +229,13 @@ fn func_call<'src>(
220229 let res = match func_name {
221230 "any" => c. args1 ( Expr :: Any ) ,
222231 "all" => c. args1 ( Expr :: All ) ,
223- "zoom" => Ok ( Expr :: Zoom ) ,
232+ "not" => c. args1 ( Expr :: Not ) ,
233+
224234 "get" => c. args1 ( Expr :: Get ) ,
235+ "in" => c. args2 ( |needle, haystack| Expr :: In { needle, haystack } ) ,
236+
237+ "geom_type" => Ok ( Expr :: GeomType ) ,
238+ "zoom" => Ok ( Expr :: Zoom ) ,
225239 _ => c. unknown ( ) ,
226240 }
227241 . and_then ( |r| {
@@ -398,7 +412,7 @@ mod tests {
398412 }
399413
400414 #[ test]
401- fn parse_literals ( ) {
415+ fn parse_atoms ( ) {
402416 let cases = [
403417 ( "42" , 42.0 . into ( ) ) ,
404418 ( "42." , 42.0 . into ( ) ) ,
@@ -451,6 +465,24 @@ mod tests {
451465 Expr :: Get ( "bool_prop" . to_owned( ) ) ,
452466 ] ) ,
453467 ) ,
468+ ( "not(true)" , Expr :: Not ( Box :: new ( true . into ( ) ) ) ) ,
469+ (
470+ "not(not(bool_prop))" ,
471+ Expr :: Not ( Box :: new ( Expr :: Not ( Box :: new ( Expr :: Get (
472+ "bool_prop" . to_string ( ) ,
473+ ) ) ) ) ) ,
474+ ) ,
475+ (
476+ "in(param, ['candidate1', 'candidate2'])" ,
477+ Expr :: In {
478+ needle : Box :: new ( Expr :: Get ( "param" . to_owned ( ) ) ) ,
479+ haystack : vec ! [
480+ "candidate1" . to_owned( ) . into( ) ,
481+ "candidate2" . to_owned( ) . into( ) ,
482+ ] ,
483+ } ,
484+ ) ,
485+ ( "geom_type()" , Expr :: GeomType ) ,
454486 ] ;
455487
456488 for ( case, expected) in cases {
@@ -547,4 +579,14 @@ mod tests {
547579 fn parser_error_invalid_argument_type_array ( ) {
548580 ass ! ( s( "any(true)" ) , @r#""expected `[Array]` argument at position `1` of function `any`, but got `true` at 4..8""# ) ;
549581 }
582+
583+ #[ test]
584+ fn parser_error_unclosed_bracket ( ) {
585+ ass ! ( s( "zoom(" ) , @r#""found end of input at 5..5 expected ''['', ''('', expression block, literal, any, property name, or '')''""# ) ;
586+ }
587+
588+ #[ test]
589+ fn parser_error_unclosed_array ( ) {
590+ ass ! ( s( "any([true, false)" ) , @r#""found '')'' at 16..17 expected ==, !=, >, >=, <, <=, '','', or '']''""# ) ;
591+ }
550592}
0 commit comments