Skip to content

Commit 564e3fc

Browse files
authored
Fix default features, cleanup dependencies & other minor code improvements (#109)
* Cleanup features - Enabled default features specified in the spec. - Removed patch versions from crates with stable minors. - Added better support for number casting. - Cleaned up imports. Signed-off-by: Tin Švagelj <tin.svagelj@live.com> * Enable serde by default Signed-off-by: Tin Švagelj <tin.svagelj@live.com> * Add type constraint for Value casting Signed-off-by: Tin Švagelj <tin.svagelj@live.com> * Revert serde separation Signed-off-by: Tin Švagelj <tin.svagelj@live.com> --------- Signed-off-by: Tin Švagelj <tin.svagelj@live.com>
1 parent 5b02b08 commit 564e3fc

File tree

6 files changed

+73
-54
lines changed

6 files changed

+73
-54
lines changed

example/Cargo.toml

+25-15
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,58 @@ name = "example"
33
version = "0.1.0"
44
edition = "2021"
55

6+
[features]
7+
axum = ["dep:axum", "dep:tokio", "dep:thiserror"]
8+
json = ["dep:serde_json", "cel-interpreter/json"]
9+
chrono = ["dep:chrono", "cel-interpreter/chrono"]
10+
611
[dependencies]
12+
cel-interpreter = { path = "../interpreter", default-features = false }
13+
14+
chrono = { version = "0.4", optional = true }
15+
16+
serde = { version = "1.0", features = ["derive"] }
17+
serde_json = { version = "1.0", optional = true }
18+
719
axum = { version = "0.7.5", default-features = false, features = [
820
"http1",
921
"json",
1022
"tokio",
11-
] }
12-
cel-interpreter = { path = "../interpreter", features = ["json", "chrono", "regex"] }
13-
chrono = "0.4.26"
14-
serde = { version = "1.0.196", features = ["derive"] }
15-
serde_json = "1.0.124"
16-
thiserror = { version = "1.0.61", default-features = false }
23+
], optional = true }
1724
tokio = { version = "1.38.0", default-features = false, features = [
1825
"macros",
1926
"net",
2027
"rt-multi-thread",
21-
] }
28+
], optional = true }
29+
thiserror = { version = "1.0", optional = true }
2230

2331
[[bin]]
24-
name = "simple"
32+
name = "example-simple"
2533
path = "src/simple.rs"
2634

2735
[[bin]]
28-
name = "variables"
36+
name = "example-variables"
2937
path = "src/variables.rs"
3038

3139
[[bin]]
32-
name = "functions"
40+
name = "example-functions"
3341
path = "src/functions.rs"
42+
required-features = ["chrono"]
3443

3544
[[bin]]
36-
name = "threads"
45+
name = "example-threads"
3746
path = "src/threads.rs"
3847

3948
[[bin]]
40-
name = "serde"
49+
name = "example-serde"
4150
path = "src/serde.rs"
4251

4352
[[bin]]
44-
name = "axum"
53+
name = "example-axum"
4554
path = "src/axum.rs"
55+
required-features = ["axum"]
4656

4757
[[bin]]
48-
name = "json"
58+
name = "example-json"
4959
path = "src/json.rs"
50-
60+
required-features = ["json"]

interpreter/Cargo.toml

+10-6
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@ categories = ["compilers"]
1010

1111
[dependencies]
1212
cel-parser = { path = "../parser", version = "0.8.0" }
13-
thiserror = "1.0.40"
14-
chrono = { version = "0.4.26", default-features = false, features = ["alloc"], optional = true }
13+
1514
nom = "7.1.3"
16-
paste = "1.0.14"
17-
serde = "1.0.196"
15+
16+
chrono = { version = "0.4", default-features = false, features = ["alloc"], optional = true }
1817
regex = { version = "1.10.5", optional = true }
19-
serde_json = { version = "1.0.124", optional = true }
18+
serde = "1.0"
19+
serde_json = { version = "1.0", optional = true }
2020
base64 = { version = "0.22.1", optional = true }
2121

22+
thiserror = "1.0"
23+
paste = "1.0"
24+
2225
[dev-dependencies]
2326
criterion = { version = "0.5.1", features = ["html_reports"] }
2427
serde_bytes = "0.11.14"
@@ -28,6 +31,7 @@ name = "runtime"
2831
harness = false
2932

3033
[features]
31-
json = ["dep:base64", "dep:serde_json"]
34+
default = ["regex", "chrono"]
35+
json = ["dep:serde_json", "dep:base64"]
3236
regex = ["dep:regex"]
3337
chrono = ["dep:chrono"]

interpreter/src/functions.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -645,10 +645,7 @@ pub fn max(Arguments(args): Arguments) -> Result<Value> {
645645
#[cfg(test)]
646646
mod tests {
647647
use crate::context::Context;
648-
use crate::testing::test_script;
649-
#[cfg(feature = "regex")]
650-
use crate::ExecutionError::FunctionError;
651-
use std::collections::HashMap;
648+
use crate::tests::test_script;
652649

653650
fn assert_script(input: &(&str, &str)) {
654651
assert_eq!(test_script(input.1, None), Ok(true.into()), "{}", input.0);
@@ -679,7 +676,7 @@ mod tests {
679676

680677
for (name, script) in tests {
681678
let mut ctx = Context::default();
682-
ctx.add_variable_from_value("foo", HashMap::from([("bar", 1)]));
679+
ctx.add_variable_from_value("foo", std::collections::HashMap::from([("bar", 1)]));
683680
assert_eq!(test_script(script, Some(ctx)), Ok(true.into()), "{}", name);
684681
}
685682
}
@@ -943,7 +940,7 @@ mod tests {
943940
test_script(
944941
"'foobar'.matches('(foo') == true", None),
945942
Err(
946-
FunctionError {
943+
crate::ExecutionError::FunctionError {
947944
function: "matches".to_string(),
948945
message: "'(foo' not a valid regex:\nregex parse error:\n (foo\n ^\nerror: unclosed group".to_string()
949946
}

interpreter/src/lib.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@ pub use cel_parser::Expression;
1313
pub use context::Context;
1414
pub use functions::FunctionContext;
1515
pub use objects::{ResolveResult, Value};
16-
#[cfg(feature = "chrono")]
17-
mod duration;
1816
pub mod functions;
1917
mod magic;
2018
pub mod objects;
2119
mod resolvers;
20+
21+
#[cfg(feature = "chrono")]
22+
mod duration;
23+
2224
mod ser;
2325
pub use ser::to_value;
2426

2527
#[cfg(feature = "json")]
2628
mod json;
27-
#[cfg(test)]
28-
mod testing;
2929

3030
use magic::FromContext;
3131

@@ -173,11 +173,16 @@ impl TryFrom<&str> for Program {
173173
mod tests {
174174
use crate::context::Context;
175175
use crate::objects::{ResolveResult, Value};
176-
use crate::testing::test_script;
177176
use crate::{ExecutionError, Program};
178177
use std::collections::HashMap;
179178
use std::convert::TryInto;
180179

180+
/// Tests the provided script and returns the result. An optional context can be provided.
181+
pub(crate) fn test_script(script: &str, ctx: Option<Context>) -> ResolveResult {
182+
let program = Program::compile(script).unwrap();
183+
program.execute(&ctx.unwrap_or_default())
184+
}
185+
181186
#[test]
182187
fn parse() {
183188
Program::compile("1 + 1").unwrap();

interpreter/src/objects.rs

+25-13
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
use crate::context::Context;
22
use crate::functions::FunctionContext;
3-
use crate::ser::SerializationError;
4-
use crate::ExecutionError::NoSuchKey;
5-
use crate::{to_value, ExecutionError};
6-
use cel_parser::{ArithmeticOp, Atom, Expression, Member, RelationOp, UnaryOp};
7-
use core::ops;
8-
use serde::{Serialize, Serializer};
3+
use crate::ExecutionError;
4+
use cel_parser::ast::*;
95
use std::cmp::Ordering;
106
use std::collections::HashMap;
117
use std::convert::{Infallible, TryFrom, TryInto};
128
use std::fmt::{Display, Formatter};
9+
use std::ops;
1310
use std::sync::Arc;
1411

1512
#[derive(Debug, PartialEq, Clone)]
@@ -84,10 +81,10 @@ impl From<u64> for Key {
8481
}
8582
}
8683

87-
impl Serialize for Key {
84+
impl serde::Serialize for Key {
8885
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
8986
where
90-
S: Serializer,
87+
S: serde::Serializer,
9188
{
9289
match self {
9390
Key::Int(v) => v.serialize(serializer),
@@ -143,13 +140,12 @@ pub trait TryIntoValue {
143140
fn try_into_value(self) -> Result<Value, Self::Error>;
144141
}
145142

146-
impl<T: Serialize> TryIntoValue for T {
147-
type Error = SerializationError;
143+
impl<T: serde::Serialize> TryIntoValue for T {
144+
type Error = crate::ser::SerializationError;
148145
fn try_into_value(self) -> Result<Value, Self::Error> {
149-
to_value(self)
146+
crate::ser::to_value(self)
150147
}
151148
}
152-
153149
impl TryIntoValue for Value {
154150
type Error = Infallible;
155151
fn try_into_value(self) -> Result<Value, Self::Error> {
@@ -629,7 +625,7 @@ impl<'a> Value {
629625
// give priority to the property. Maybe we can implement lookahead
630626
// to see if the next token is a function call?
631627
match (child, ctx.has_function(&***name)) {
632-
(None, false) => NoSuchKey(name.clone()).into(),
628+
(None, false) => ExecutionError::NoSuchKey(name.clone()).into(),
633629
(Some(child), _) => child.into(),
634630
(None, true) => Value::Function(name.clone(), Some(self.into())).into(),
635631
}
@@ -960,4 +956,20 @@ mod tests {
960956
let result = program.execute(&context);
961957
assert_eq!(result.unwrap(), Value::Null);
962958
}
959+
960+
#[test]
961+
fn reference_to_value() {
962+
let test = "example".to_string();
963+
let direct: Value = test.as_str().into();
964+
assert_eq!(direct, Value::String(Arc::new(String::from("example"))));
965+
966+
let vec = vec![test.as_str()];
967+
let indirect: Value = vec.into();
968+
assert_eq!(
969+
indirect,
970+
Value::List(Arc::new(vec![Value::String(Arc::new(String::from(
971+
"example"
972+
)))]))
973+
);
974+
}
963975
}

interpreter/src/testing.rs

-9
This file was deleted.

0 commit comments

Comments
 (0)