Skip to content

Commit 124cb5a

Browse files
committed
Introduce SchemeBuilder to build a Scheme
This makes the scheme immutable and allows to tailor its internals for parsing and execution of filter expressions.
1 parent 3054789 commit 124cb5a

File tree

18 files changed

+319
-290
lines changed

18 files changed

+319
-290
lines changed

engine/benches/bench.rs

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

@@ -79,11 +79,12 @@ impl<T: 'static + Copy + Debug + Into<LhsValue<'static>>> FieldBench<'_, T> {
7979
let mut group = c.benchmark_group("parsing");
8080

8181
group.bench_function(name, {
82-
let mut scheme = Scheme::default();
83-
scheme.add_field(field, ty).unwrap();
82+
let mut builder = SchemeBuilder::default();
83+
builder.add_field(field, ty).unwrap();
8484
for (name, function) in functions {
85-
scheme.add_function(name, function.clone()).unwrap();
85+
builder.add_function(name, function.clone()).unwrap();
8686
}
87+
let scheme = builder.build();
8788
move |b: &mut Bencher| {
8889
b.iter(|| scheme.parse(filter).unwrap());
8990
}
@@ -94,11 +95,12 @@ impl<T: 'static + Copy + Debug + Into<LhsValue<'static>>> FieldBench<'_, T> {
9495
let mut group = c.benchmark_group("compilation");
9596

9697
group.bench_function(name, {
97-
let mut scheme = Scheme::default();
98-
scheme.add_field(field, ty).unwrap();
98+
let mut builder = SchemeBuilder::default();
99+
builder.add_field(field, ty).unwrap();
99100
for (name, function) in functions {
100-
scheme.add_function(name, function.clone()).unwrap();
101+
builder.add_function(name, function.clone()).unwrap();
101102
}
103+
let scheme = builder.build();
102104
move |b: &mut Bencher| {
103105
let filter = scheme.parse(filter).unwrap();
104106

@@ -111,11 +113,12 @@ impl<T: 'static + Copy + Debug + Into<LhsValue<'static>>> FieldBench<'_, T> {
111113
let mut group = c.benchmark_group("execution");
112114

113115
group.bench_with_input(name, values, {
114-
let mut scheme = Scheme::default();
115-
scheme.add_field(field, ty).unwrap();
116+
let mut builder = SchemeBuilder::default();
117+
builder.add_field(field, ty).unwrap();
116118
for (name, function) in functions {
117-
scheme.add_function(name, function.clone()).unwrap();
119+
builder.add_function(name, function.clone()).unwrap();
118120
}
121+
let scheme = builder.build();
119122
move |b: &mut Bencher, values: &[T]| {
120123
let filter = scheme.parse(filter).unwrap();
121124

engine/examples/cli.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn main() {
1313
.nth(1)
1414
.expect("Expected an input as a command-line argument");
1515

16-
let mut scheme = Scheme! {
16+
let mut builder = Scheme! {
1717
ip: Ip,
1818
str: Bytes,
1919
int: Int,
@@ -23,7 +23,7 @@ fn main() {
2323
bool_arr: Array(Bool),
2424
};
2525

26-
scheme
26+
builder
2727
.add_function(
2828
"panic",
2929
SimpleFunctionDefinition {
@@ -41,6 +41,8 @@ fn main() {
4141
)
4242
.unwrap();
4343

44+
let scheme = builder.build();
45+
4446
match scheme.parse(&filter) {
4547
Ok(res) => println!("{res:#?}"),
4648
Err(err) => println!("{err}"),

engine/src/ast/field_expr.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ mod tests {
805805
}
806806

807807
static SCHEME: LazyLock<Scheme> = LazyLock::new(|| {
808-
let mut scheme: Scheme = Scheme! {
808+
let mut builder = Scheme! {
809809
http.cookies: Array(Bytes),
810810
http.headers: Map(Bytes),
811811
http.host: Bytes,
@@ -816,7 +816,7 @@ mod tests {
816816
array.of.bool: Array(Bool),
817817
http.parts: Array(Array(Bytes)),
818818
};
819-
scheme
819+
builder
820820
.add_function(
821821
"any",
822822
SimpleFunctionDefinition {
@@ -830,7 +830,7 @@ mod tests {
830830
},
831831
)
832832
.unwrap();
833-
scheme
833+
builder
834834
.add_function(
835835
"echo",
836836
SimpleFunctionDefinition {
@@ -844,7 +844,7 @@ mod tests {
844844
},
845845
)
846846
.unwrap();
847-
scheme
847+
builder
848848
.add_function(
849849
"lowercase",
850850
SimpleFunctionDefinition {
@@ -858,7 +858,7 @@ mod tests {
858858
},
859859
)
860860
.unwrap();
861-
scheme
861+
builder
862862
.add_function(
863863
"concat",
864864
SimpleFunctionDefinition {
@@ -878,10 +878,10 @@ mod tests {
878878
},
879879
)
880880
.unwrap();
881-
scheme
881+
builder
882882
.add_function("filter", FilterFunction::new())
883883
.unwrap();
884-
scheme
884+
builder
885885
.add_function(
886886
"len",
887887
SimpleFunctionDefinition {
@@ -895,10 +895,10 @@ mod tests {
895895
},
896896
)
897897
.unwrap();
898-
scheme
898+
builder
899899
.add_list(Type::Int, Box::new(NumMListDefinition {}))
900900
.unwrap();
901-
scheme
901+
builder.build()
902902
});
903903

904904
fn field(name: &'static str) -> Field<'static> {

engine/src/ast/function_expr.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ mod tests {
592592
}
593593

594594
static SCHEME: LazyLock<Scheme> = LazyLock::new(|| {
595-
let mut scheme = Scheme! {
595+
let mut builder = Scheme! {
596596
http.headers: Map(Bytes),
597597
http.host: Bytes,
598598
http.request.headers.names: Array(Bytes),
@@ -602,7 +602,7 @@ mod tests {
602602
ssl: Bool,
603603
tcp.port: Int,
604604
};
605-
scheme
605+
builder
606606
.add_function(
607607
"any",
608608
SimpleFunctionDefinition {
@@ -616,7 +616,7 @@ mod tests {
616616
},
617617
)
618618
.unwrap();
619-
scheme
619+
builder
620620
.add_function(
621621
"echo",
622622
SimpleFunctionDefinition {
@@ -639,7 +639,7 @@ mod tests {
639639
},
640640
)
641641
.unwrap();
642-
scheme
642+
builder
643643
.add_function(
644644
"lower",
645645
SimpleFunctionDefinition {
@@ -653,7 +653,7 @@ mod tests {
653653
},
654654
)
655655
.unwrap();
656-
scheme
656+
builder
657657
.add_function(
658658
"regex_replace",
659659
SimpleFunctionDefinition {
@@ -677,7 +677,7 @@ mod tests {
677677
},
678678
)
679679
.unwrap();
680-
scheme
680+
builder
681681
.add_function(
682682
"len",
683683
SimpleFunctionDefinition {
@@ -691,7 +691,7 @@ mod tests {
691691
},
692692
)
693693
.unwrap();
694-
scheme
694+
builder.build()
695695
});
696696

697697
#[test]

engine/src/ast/index_expr.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -548,8 +548,8 @@ mod tests {
548548
use super::*;
549549
use crate::{
550550
ast::field_expr::IdentifierExpr, Array, FieldIndex, FilterParser, FunctionArgKind,
551-
FunctionArgs, FunctionCallArgExpr, FunctionCallExpr, Scheme, SimpleFunctionDefinition,
552-
SimpleFunctionImpl, SimpleFunctionParam,
551+
FunctionArgs, FunctionCallArgExpr, FunctionCallExpr, Scheme, SchemeBuilder,
552+
SimpleFunctionDefinition, SimpleFunctionImpl, SimpleFunctionParam,
553553
};
554554
use std::sync::LazyLock;
555555

@@ -574,17 +574,17 @@ mod tests {
574574
}
575575

576576
static SCHEME: LazyLock<Scheme> = LazyLock::new(|| {
577-
let mut scheme = Scheme::new();
578-
scheme
577+
let mut builder = SchemeBuilder::new();
578+
builder
579579
.add_field("test", Type::Array(Type::Bytes.into()))
580580
.unwrap();
581-
scheme
581+
builder
582582
.add_field("test2", Type::Array(Type::Array(Type::Bytes.into()).into()))
583583
.unwrap();
584-
scheme
584+
builder
585585
.add_field("map", Type::Map(Type::Bytes.into()))
586586
.unwrap();
587-
scheme
587+
builder
588588
.add_function(
589589
"array",
590590
SimpleFunctionDefinition {
@@ -598,7 +598,7 @@ mod tests {
598598
},
599599
)
600600
.unwrap();
601-
scheme
601+
builder
602602
.add_function(
603603
"array2",
604604
SimpleFunctionDefinition {
@@ -612,7 +612,7 @@ mod tests {
612612
},
613613
)
614614
.unwrap();
615-
scheme
615+
builder.build()
616616
});
617617

618618
#[test]

engine/src/ast/logical_expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,8 @@ fn test() {
345345
at: Array(Bool),
346346
af: Array(Bool),
347347
aat: Array(Array(Bool)),
348-
};
348+
}
349+
.build();
349350

350351
let ctx = &mut ExecutionContext::new(scheme);
351352

engine/src/ast/visitor.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ mod tests {
225225
use std::sync::LazyLock;
226226

227227
static SCHEME: LazyLock<Scheme> = LazyLock::new(|| {
228-
let mut scheme = Scheme! {
228+
let mut builder = Scheme! {
229229
http.headers: Map(Bytes),
230230
http.request.headers.names: Array(Bytes),
231231
http.request.headers.values: Array(Bytes),
@@ -234,7 +234,7 @@ mod tests {
234234
ssl: Bool,
235235
tcp.port: Int,
236236
};
237-
scheme
237+
builder
238238
.add_function(
239239
"echo",
240240
SimpleFunctionDefinition {
@@ -248,10 +248,10 @@ mod tests {
248248
},
249249
)
250250
.unwrap();
251-
scheme
251+
builder
252252
.add_list(Type::Bytes, Box::new(AlwaysList {}))
253253
.unwrap();
254-
scheme
254+
builder.build()
255255
});
256256

257257
#[test]

engine/src/execution_context.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ impl Serialize for ExecutionContext<'_> {
355355
fn test_field_value_type_mismatch() {
356356
use crate::types::Type;
357357

358-
let scheme = Scheme! { foo: Int };
358+
let scheme = Scheme! { foo: Int }.build();
359359

360360
let mut ctx = ExecutionContext::<()>::new(&scheme);
361361

@@ -370,11 +370,11 @@ fn test_field_value_type_mismatch() {
370370

371371
#[test]
372372
fn test_scheme_mismatch() {
373-
let scheme = Scheme! { foo: Bool };
373+
let scheme = Scheme! { foo: Bool }.build();
374374

375375
let mut ctx = ExecutionContext::<()>::new(&scheme);
376376

377-
let scheme2 = Scheme! { foo: Bool };
377+
let scheme2 = Scheme! { foo: Bool }.build();
378378

379379
assert_eq!(
380380
ctx.set_field_value(scheme2.get_field("foo").unwrap(), LhsValue::Bool(false)),
@@ -391,20 +391,18 @@ fn test_serde() {
391391
use std::net::IpAddr;
392392
use std::str::FromStr;
393393

394-
let mut scheme = Scheme::new();
395-
scheme.add_field("bool", Type::Bool).unwrap();
396-
scheme.add_field("ip", Type::Ip).unwrap();
397-
scheme.add_field("str", Type::Bytes).unwrap();
398-
scheme.add_field("bytes", Type::Bytes).unwrap();
399-
scheme.add_field("num", Type::Int).unwrap();
400-
scheme.add_field("min_num", Type::Int).unwrap();
401-
scheme.add_field("max_num", Type::Int).unwrap();
402-
scheme
403-
.add_field("arr", Type::Array(Type::Bool.into()))
404-
.unwrap();
405-
scheme
406-
.add_field("map", Type::Map(Type::Int.into()))
407-
.unwrap();
394+
let scheme = Scheme! {
395+
bool: Bool,
396+
ip: Ip,
397+
str: Bytes,
398+
bytes: Bytes,
399+
num: Int,
400+
min_num: Int,
401+
max_num: Int,
402+
arr: Array(Bool),
403+
map: Map(Int),
404+
}
405+
.build();
408406

409407
let mut ctx = ExecutionContext::new(&scheme);
410408

@@ -550,13 +548,14 @@ fn test_serde() {
550548

551549
#[test]
552550
fn test_clear() {
553-
use crate::types::Type;
554551
use std::net::IpAddr;
555552
use std::str::FromStr;
556553

557-
let mut scheme = Scheme::new();
558-
scheme.add_field("bool", Type::Bool).unwrap();
559-
scheme.add_field("ip", Type::Ip).unwrap();
554+
let scheme = Scheme! {
555+
bool: Bool,
556+
ip: Ip,
557+
}
558+
.build();
560559

561560
let bool_field = scheme.get_field("bool").unwrap();
562561
let ip_field = scheme.get_field("ip").unwrap();

engine/src/filter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ mod tests {
244244

245245
#[test]
246246
fn test_scheme_mismatch() {
247-
let scheme1 = Scheme! { foo: Int };
248-
let scheme2 = Scheme! { foo: Int, bar: Int };
247+
let scheme1 = Scheme! { foo: Int }.build();
248+
let scheme2 = Scheme! { foo: Int, bar: Int }.build();
249249
let filter = scheme1.parse("foo == 42").unwrap().compile();
250250
let ctx = ExecutionContext::new(&scheme2);
251251

0 commit comments

Comments
 (0)