Skip to content

Commit 162a544

Browse files
committed
Support simple functions accepting either literal or field arguments
1 parent 263c144 commit 162a544

File tree

11 files changed

+89
-62
lines changed

11 files changed

+89
-62
lines changed

engine/benches/bench.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ static A: System = System;
88
use criterion::{Bencher, Criterion, criterion_group, criterion_main};
99
use std::{borrow::Cow, clone::Clone, fmt::Debug, net::IpAddr};
1010
use wirefilter::{
11-
ExecutionContext, FilterAst, FunctionArgKind, FunctionArgs, GetType, LhsValue, SchemeBuilder,
12-
SimpleFunctionDefinition, SimpleFunctionImpl, SimpleFunctionParam, Type,
11+
ExecutionContext, FilterAst, FunctionArgs, GetType, LhsValue, SchemeBuilder,
12+
SimpleFunctionArgKind, SimpleFunctionDefinition, SimpleFunctionImpl, SimpleFunctionParam, Type,
1313
};
1414

1515
fn lowercase<'a>(args: FunctionArgs<'_, 'a>) -> Option<LhsValue<'a>> {
@@ -209,7 +209,7 @@ fn bench_string_function_comparison(c: &mut Criterion) {
209209
"lowercase",
210210
SimpleFunctionDefinition {
211211
params: vec![SimpleFunctionParam {
212-
arg_kind: FunctionArgKind::Field,
212+
arg_kind: SimpleFunctionArgKind::Field,
213213
val_type: Type::Bytes,
214214
}],
215215
opt_params: vec![],
@@ -221,7 +221,7 @@ fn bench_string_function_comparison(c: &mut Criterion) {
221221
"uppercase",
222222
SimpleFunctionDefinition {
223223
params: vec![SimpleFunctionParam {
224-
arg_kind: FunctionArgKind::Field,
224+
arg_kind: SimpleFunctionArgKind::Field,
225225
val_type: Type::Bytes,
226226
}],
227227
opt_params: vec![],

engine/examples/cli.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::env::args;
22
use wirefilter::{
3-
FunctionArgKind, FunctionArgs, LhsValue, Scheme, SimpleFunctionDefinition, SimpleFunctionImpl,
4-
SimpleFunctionOptParam, SimpleFunctionParam, Type,
3+
FunctionArgs, LhsValue, Scheme, SimpleFunctionArgKind, SimpleFunctionDefinition,
4+
SimpleFunctionImpl, SimpleFunctionOptParam, SimpleFunctionParam, Type,
55
};
66

77
fn panic_function<'a>(_: FunctionArgs<'_, 'a>) -> Option<LhsValue<'a>> {
@@ -28,11 +28,11 @@ fn main() {
2828
"panic",
2929
SimpleFunctionDefinition {
3030
params: vec![SimpleFunctionParam {
31-
arg_kind: FunctionArgKind::Field,
31+
arg_kind: SimpleFunctionArgKind::Field,
3232
val_type: Type::Bytes,
3333
}],
3434
opt_params: vec![SimpleFunctionOptParam {
35-
arg_kind: FunctionArgKind::Literal,
35+
arg_kind: SimpleFunctionArgKind::Literal,
3636
default_value: "".into(),
3737
}],
3838
return_type: Type::Bytes,

engine/src/ast/field_expr.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,8 @@ impl Expr for ComparisonExpr {
799799
mod tests {
800800
use super::*;
801801
use crate::{
802-
BytesFormat, FieldRef, LhsValue, ParserSettings, SchemeBuilder, TypedMap,
802+
BytesFormat, FieldRef, LhsValue, ParserSettings, SchemeBuilder, SimpleFunctionArgKind,
803+
TypedMap,
803804
ast::{
804805
function_expr::{FunctionCallArgExpr, FunctionCallExpr},
805806
logical_expr::LogicalExpr,
@@ -878,11 +879,11 @@ mod tests {
878879
) -> Result<(), FunctionParamError> {
879880
match params.len() {
880881
0 => {
881-
next_param.expect_arg_kind(FunctionArgKind::Field)?;
882+
next_param.arg_kind().expect(FunctionArgKind::Field)?;
882883
next_param.expect_val_type(once(ExpectedType::Array))?;
883884
}
884885
1 => {
885-
next_param.expect_arg_kind(FunctionArgKind::Field)?;
886+
next_param.arg_kind().expect(FunctionArgKind::Field)?;
886887
next_param.expect_val_type(once(ExpectedType::Type(Type::Array(
887888
Type::Bool.into(),
888889
))))?;
@@ -979,7 +980,7 @@ mod tests {
979980
"any",
980981
SimpleFunctionDefinition {
981982
params: vec![SimpleFunctionParam {
982-
arg_kind: FunctionArgKind::Field,
983+
arg_kind: SimpleFunctionArgKind::Field,
983984
val_type: Type::Array(Type::Bool.into()),
984985
}],
985986
opt_params: vec![],
@@ -993,7 +994,7 @@ mod tests {
993994
"echo",
994995
SimpleFunctionDefinition {
995996
params: vec![SimpleFunctionParam {
996-
arg_kind: FunctionArgKind::Field,
997+
arg_kind: SimpleFunctionArgKind::Field,
997998
val_type: Type::Bytes,
998999
}],
9991000
opt_params: vec![],
@@ -1007,7 +1008,7 @@ mod tests {
10071008
"lowercase",
10081009
SimpleFunctionDefinition {
10091010
params: vec![SimpleFunctionParam {
1010-
arg_kind: FunctionArgKind::Field,
1011+
arg_kind: SimpleFunctionArgKind::Field,
10111012
val_type: Type::Bytes,
10121013
}],
10131014
opt_params: vec![],
@@ -1023,11 +1024,11 @@ mod tests {
10231024
params: vec![],
10241025
opt_params: vec![
10251026
SimpleFunctionOptParam {
1026-
arg_kind: FunctionArgKind::Field,
1027+
arg_kind: SimpleFunctionArgKind::Field,
10271028
default_value: "".into(),
10281029
},
10291030
SimpleFunctionOptParam {
1030-
arg_kind: FunctionArgKind::Literal,
1031+
arg_kind: SimpleFunctionArgKind::Literal,
10311032
default_value: "".into(),
10321033
},
10331034
],
@@ -1044,7 +1045,7 @@ mod tests {
10441045
"len",
10451046
SimpleFunctionDefinition {
10461047
params: vec![SimpleFunctionParam {
1047-
arg_kind: FunctionArgKind::Field,
1048+
arg_kind: SimpleFunctionArgKind::Field,
10481049
val_type: Type::Bytes,
10491050
}],
10501051
opt_params: vec![],

engine/src/ast/function_expr.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ impl<'i> LexWith<'i, &FilterParser<'_>> for FunctionCallExpr {
527527
mod tests {
528528
use super::*;
529529
use crate::{
530+
SimpleFunctionArgKind,
530531
ast::{
531532
field_expr::{ComparisonExpr, ComparisonOpExpr, IdentifierExpr, OrderingOp},
532533
logical_expr::{LogicalExpr, LogicalOp, ParenthesizedExpr},
@@ -602,7 +603,7 @@ mod tests {
602603
"any",
603604
SimpleFunctionDefinition {
604605
params: vec![SimpleFunctionParam {
605-
arg_kind: FunctionArgKind::Field,
606+
arg_kind: SimpleFunctionArgKind::Field,
606607
val_type: Type::Array(Type::Bool.into()),
607608
}],
608609
opt_params: vec![],
@@ -616,16 +617,16 @@ mod tests {
616617
"echo",
617618
SimpleFunctionDefinition {
618619
params: vec![SimpleFunctionParam {
619-
arg_kind: FunctionArgKind::Field,
620+
arg_kind: SimpleFunctionArgKind::Field,
620621
val_type: Type::Bytes,
621622
}],
622623
opt_params: vec![
623624
SimpleFunctionOptParam {
624-
arg_kind: FunctionArgKind::Literal,
625+
arg_kind: SimpleFunctionArgKind::Literal,
625626
default_value: LhsValue::Int(10),
626627
},
627628
SimpleFunctionOptParam {
628-
arg_kind: FunctionArgKind::Literal,
629+
arg_kind: SimpleFunctionArgKind::Literal,
629630
default_value: LhsValue::Int(1),
630631
},
631632
],
@@ -639,7 +640,7 @@ mod tests {
639640
"lower",
640641
SimpleFunctionDefinition {
641642
params: vec![SimpleFunctionParam {
642-
arg_kind: FunctionArgKind::Field,
643+
arg_kind: SimpleFunctionArgKind::Field,
643644
val_type: Type::Bytes,
644645
}],
645646
opt_params: vec![],
@@ -654,15 +655,15 @@ mod tests {
654655
SimpleFunctionDefinition {
655656
params: vec![
656657
SimpleFunctionParam {
657-
arg_kind: FunctionArgKind::Field,
658+
arg_kind: SimpleFunctionArgKind::Field,
658659
val_type: Type::Bytes,
659660
},
660661
SimpleFunctionParam {
661-
arg_kind: FunctionArgKind::Literal,
662+
arg_kind: SimpleFunctionArgKind::Literal,
662663
val_type: Type::Bytes,
663664
},
664665
SimpleFunctionParam {
665-
arg_kind: FunctionArgKind::Literal,
666+
arg_kind: SimpleFunctionArgKind::Literal,
666667
val_type: Type::Bytes,
667668
},
668669
],
@@ -677,7 +678,7 @@ mod tests {
677678
"len",
678679
SimpleFunctionDefinition {
679680
params: vec![SimpleFunctionParam {
680-
arg_kind: FunctionArgKind::Field,
681+
arg_kind: SimpleFunctionArgKind::Field,
681682
val_type: Type::Bytes,
682683
}],
683684
opt_params: vec![],

engine/src/ast/index_expr.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,8 @@ impl<'a> Iterator for MapEachIterator<'a, '_> {
529529
mod tests {
530530
use super::*;
531531
use crate::{
532-
Array, FieldIndex, FilterParser, FunctionArgKind, FunctionArgs, FunctionCallArgExpr,
533-
FunctionCallExpr, Scheme, SchemeBuilder, SimpleFunctionDefinition, SimpleFunctionImpl,
532+
Array, FieldIndex, FilterParser, FunctionArgs, FunctionCallArgExpr, FunctionCallExpr,
533+
Scheme, SchemeBuilder, SimpleFunctionArgKind, SimpleFunctionDefinition, SimpleFunctionImpl,
534534
SimpleFunctionParam, ast::field_expr::IdentifierExpr,
535535
};
536536
use std::sync::LazyLock;
@@ -571,7 +571,7 @@ mod tests {
571571
"array",
572572
SimpleFunctionDefinition {
573573
params: vec![SimpleFunctionParam {
574-
arg_kind: FunctionArgKind::Field,
574+
arg_kind: SimpleFunctionArgKind::Field,
575575
val_type: Type::Bytes,
576576
}],
577577
opt_params: vec![],
@@ -585,7 +585,7 @@ mod tests {
585585
"array2",
586586
SimpleFunctionDefinition {
587587
params: vec![SimpleFunctionParam {
588-
arg_kind: FunctionArgKind::Field,
588+
arg_kind: SimpleFunctionArgKind::Field,
589589
val_type: Type::Bytes,
590590
}],
591591
opt_params: vec![],

engine/src/ast/visitor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ impl Visitor<'_> for UsesListVisitor<'_> {
219219
#[cfg(test)]
220220
mod tests {
221221
use crate::{
222-
AlwaysList, FunctionArgKind, Scheme, SimpleFunctionDefinition, SimpleFunctionImpl,
222+
AlwaysList, Scheme, SimpleFunctionArgKind, SimpleFunctionDefinition, SimpleFunctionImpl,
223223
SimpleFunctionParam, Type,
224224
};
225225
use std::sync::LazyLock;
@@ -239,7 +239,7 @@ mod tests {
239239
"echo",
240240
SimpleFunctionDefinition {
241241
params: vec![SimpleFunctionParam {
242-
arg_kind: FunctionArgKind::Field,
242+
arg_kind: SimpleFunctionArgKind::Field,
243243
val_type: Type::Bytes,
244244
}],
245245
opt_params: vec![],

engine/src/functions/all.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl FunctionDefinition for AllFunction {
3737
) -> Result<(), FunctionParamError> {
3838
match params.len() {
3939
0 => {
40-
next_param.expect_arg_kind(FunctionArgKind::Field)?;
40+
next_param.arg_kind().expect(FunctionArgKind::Field)?;
4141
next_param.expect_val_type(once(Type::Array(Type::Bool.into()).into()))?;
4242
}
4343
_ => unreachable!(),

engine/src/functions/any.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl FunctionDefinition for AnyFunction {
3737
) -> Result<(), FunctionParamError> {
3838
match params.len() {
3939
0 => {
40-
next_param.expect_arg_kind(FunctionArgKind::Field)?;
40+
next_param.arg_kind().expect(FunctionArgKind::Field)?;
4141
next_param.expect_val_type(once(Type::Array(Type::Bool.into()).into()))?;
4242
}
4343
_ => unreachable!(),

engine/src/functions/mod.rs

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,23 @@ pub enum FunctionArgKind {
9090
Field,
9191
}
9292

93+
impl FunctionArgKind {
94+
/// Check if the current argument kind matches the expected one.
95+
pub fn expect(
96+
&self,
97+
expected_arg_kind: FunctionArgKind,
98+
) -> Result<(), FunctionArgKindMismatchError> {
99+
if self == &expected_arg_kind {
100+
Ok(())
101+
} else {
102+
Err(FunctionArgKindMismatchError {
103+
expected: expected_arg_kind,
104+
actual: *self,
105+
})
106+
}
107+
}
108+
}
109+
93110
/// An error that occurs on a kind mismatch.
94111
#[derive(Debug, PartialEq, Eq, Error)]
95112
#[error("expected argument of kind {expected:?}, but got {actual:?}")]
@@ -167,11 +184,8 @@ pub enum FunctionParam<'a> {
167184
}
168185

169186
impl From<&FunctionParam<'_>> for FunctionArgKind {
170-
fn from(arg: &FunctionParam<'_>) -> Self {
171-
match arg {
172-
FunctionParam::Constant(_) => FunctionArgKind::Literal,
173-
FunctionParam::Variable(_) => FunctionArgKind::Field,
174-
}
187+
fn from(param: &FunctionParam<'_>) -> Self {
188+
param.arg_kind()
175189
}
176190
}
177191

@@ -207,21 +221,11 @@ impl<'a> FunctionParam<'a> {
207221
}
208222
}
209223

210-
/// Check if the arg_kind of current paramater matches the expected_arg_kind
211-
pub fn expect_arg_kind(
212-
&self,
213-
expected_arg_kind: FunctionArgKind,
214-
) -> Result<(), FunctionParamError> {
215-
let kind = self.into();
216-
if kind == expected_arg_kind {
217-
Ok(())
218-
} else {
219-
Err(FunctionParamError::KindMismatch(
220-
FunctionArgKindMismatchError {
221-
expected: expected_arg_kind,
222-
actual: kind,
223-
},
224-
))
224+
/// Returns the associated argument kind.
225+
pub fn arg_kind(&self) -> FunctionArgKind {
226+
match self {
227+
FunctionParam::Constant(_) => FunctionArgKind::Literal,
228+
FunctionParam::Variable(_) => FunctionArgKind::Field,
225229
}
226230
}
227231

@@ -434,11 +438,32 @@ impl PartialEq for SimpleFunctionImpl {
434438

435439
impl Eq for SimpleFunctionImpl {}
436440

441+
/// Kind of argument the function parameter expects.
442+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
443+
pub enum SimpleFunctionArgKind {
444+
/// The parameter is expecting a literal value.
445+
Literal,
446+
/// The parameter is expecting a field / dynamic value.
447+
Field,
448+
/// The parameter is expecting either a literal or a field / dynamic value.
449+
Both,
450+
}
451+
452+
impl SimpleFunctionArgKind {
453+
fn expect(&self, arg_kind: FunctionArgKind) -> Result<(), FunctionArgKindMismatchError> {
454+
match self {
455+
SimpleFunctionArgKind::Literal => arg_kind.expect(FunctionArgKind::Literal),
456+
SimpleFunctionArgKind::Field => arg_kind.expect(FunctionArgKind::Field),
457+
SimpleFunctionArgKind::Both => Ok(()),
458+
}
459+
}
460+
}
461+
437462
/// Defines a mandatory function argument.
438463
#[derive(Debug, PartialEq, Eq, Clone)]
439464
pub struct SimpleFunctionParam {
440465
/// How the argument can be specified when calling a function.
441-
pub arg_kind: FunctionArgKind,
466+
pub arg_kind: SimpleFunctionArgKind,
442467
/// The type of its associated value.
443468
pub val_type: Type,
444469
}
@@ -447,7 +472,7 @@ pub struct SimpleFunctionParam {
447472
#[derive(Debug, PartialEq, Eq, Clone)]
448473
pub struct SimpleFunctionOptParam {
449474
/// How the argument can be specified when calling a function.
450-
pub arg_kind: FunctionArgKind,
475+
pub arg_kind: SimpleFunctionArgKind,
451476
/// The default value if the argument is missing.
452477
pub default_value: LhsValue<'static>,
453478
}
@@ -476,11 +501,11 @@ impl FunctionDefinition for SimpleFunctionDefinition {
476501
let index = params.len();
477502
if index < self.params.len() {
478503
let param = &self.params[index];
479-
next_param.expect_arg_kind(param.arg_kind)?;
504+
param.arg_kind.expect(next_param.arg_kind())?;
480505
next_param.expect_val_type(once(ExpectedType::Type(param.val_type)))?;
481506
} else if index < self.params.len() + self.opt_params.len() {
482507
let opt_param = &self.opt_params[index - self.params.len()];
483-
next_param.expect_arg_kind(opt_param.arg_kind)?;
508+
opt_param.arg_kind.expect(next_param.arg_kind())?;
484509
next_param
485510
.expect_val_type(once(ExpectedType::Type(opt_param.default_value.get_type())))?;
486511
} else {

engine/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ pub use self::{
9999
functions::{
100100
AllFunction, AnyFunction, ConcatFunction, FunctionArgInvalidConstantError, FunctionArgKind,
101101
FunctionArgKindMismatchError, FunctionArgs, FunctionDefinition, FunctionDefinitionContext,
102-
FunctionParam, FunctionParamError, SimpleFunctionDefinition, SimpleFunctionImpl,
103-
SimpleFunctionOptParam, SimpleFunctionParam,
102+
FunctionParam, FunctionParamError, SimpleFunctionArgKind, SimpleFunctionDefinition,
103+
SimpleFunctionImpl, SimpleFunctionOptParam, SimpleFunctionParam,
104104
},
105105
lex::LexErrorKind,
106106
lhs_types::{Array, Map, MapIter, TypedArray, TypedMap},

0 commit comments

Comments
 (0)