Skip to content

Commit

Permalink
Fix default features, cleanup dependencies & other minor code improve…
Browse files Browse the repository at this point in the history
…ments (#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 <[email protected]>

* Enable serde by default

Signed-off-by: Tin Švagelj <[email protected]>

* Add type constraint for Value casting

Signed-off-by: Tin Švagelj <[email protected]>

* Revert serde separation

Signed-off-by: Tin Švagelj <[email protected]>

---------

Signed-off-by: Tin Švagelj <[email protected]>
  • Loading branch information
Caellian authored Nov 6, 2024
1 parent 5b02b08 commit 564e3fc
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 54 deletions.
40 changes: 25 additions & 15 deletions example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,58 @@ name = "example"
version = "0.1.0"
edition = "2021"

[features]
axum = ["dep:axum", "dep:tokio", "dep:thiserror"]
json = ["dep:serde_json", "cel-interpreter/json"]
chrono = ["dep:chrono", "cel-interpreter/chrono"]

[dependencies]
cel-interpreter = { path = "../interpreter", default-features = false }

chrono = { version = "0.4", optional = true }

serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", optional = true }

axum = { version = "0.7.5", default-features = false, features = [
"http1",
"json",
"tokio",
] }
cel-interpreter = { path = "../interpreter", features = ["json", "chrono", "regex"] }
chrono = "0.4.26"
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.124"
thiserror = { version = "1.0.61", default-features = false }
], optional = true }
tokio = { version = "1.38.0", default-features = false, features = [
"macros",
"net",
"rt-multi-thread",
] }
], optional = true }
thiserror = { version = "1.0", optional = true }

[[bin]]
name = "simple"
name = "example-simple"
path = "src/simple.rs"

[[bin]]
name = "variables"
name = "example-variables"
path = "src/variables.rs"

[[bin]]
name = "functions"
name = "example-functions"
path = "src/functions.rs"
required-features = ["chrono"]

[[bin]]
name = "threads"
name = "example-threads"
path = "src/threads.rs"

[[bin]]
name = "serde"
name = "example-serde"
path = "src/serde.rs"

[[bin]]
name = "axum"
name = "example-axum"
path = "src/axum.rs"
required-features = ["axum"]

[[bin]]
name = "json"
name = "example-json"
path = "src/json.rs"

required-features = ["json"]
16 changes: 10 additions & 6 deletions interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ categories = ["compilers"]

[dependencies]
cel-parser = { path = "../parser", version = "0.8.0" }
thiserror = "1.0.40"
chrono = { version = "0.4.26", default-features = false, features = ["alloc"], optional = true }

nom = "7.1.3"
paste = "1.0.14"
serde = "1.0.196"

chrono = { version = "0.4", default-features = false, features = ["alloc"], optional = true }
regex = { version = "1.10.5", optional = true }
serde_json = { version = "1.0.124", optional = true }
serde = "1.0"
serde_json = { version = "1.0", optional = true }
base64 = { version = "0.22.1", optional = true }

thiserror = "1.0"
paste = "1.0"

[dev-dependencies]
criterion = { version = "0.5.1", features = ["html_reports"] }
serde_bytes = "0.11.14"
Expand All @@ -28,6 +31,7 @@ name = "runtime"
harness = false

[features]
json = ["dep:base64", "dep:serde_json"]
default = ["regex", "chrono"]
json = ["dep:serde_json", "dep:base64"]
regex = ["dep:regex"]
chrono = ["dep:chrono"]
9 changes: 3 additions & 6 deletions interpreter/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,10 +645,7 @@ pub fn max(Arguments(args): Arguments) -> Result<Value> {
#[cfg(test)]
mod tests {
use crate::context::Context;
use crate::testing::test_script;
#[cfg(feature = "regex")]
use crate::ExecutionError::FunctionError;
use std::collections::HashMap;
use crate::tests::test_script;

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

for (name, script) in tests {
let mut ctx = Context::default();
ctx.add_variable_from_value("foo", HashMap::from([("bar", 1)]));
ctx.add_variable_from_value("foo", std::collections::HashMap::from([("bar", 1)]));
assert_eq!(test_script(script, Some(ctx)), Ok(true.into()), "{}", name);
}
}
Expand Down Expand Up @@ -943,7 +940,7 @@ mod tests {
test_script(
"'foobar'.matches('(foo') == true", None),
Err(
FunctionError {
crate::ExecutionError::FunctionError {
function: "matches".to_string(),
message: "'(foo' not a valid regex:\nregex parse error:\n (foo\n ^\nerror: unclosed group".to_string()
}
Expand Down
15 changes: 10 additions & 5 deletions interpreter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ pub use cel_parser::Expression;
pub use context::Context;
pub use functions::FunctionContext;
pub use objects::{ResolveResult, Value};
#[cfg(feature = "chrono")]
mod duration;
pub mod functions;
mod magic;
pub mod objects;
mod resolvers;

#[cfg(feature = "chrono")]
mod duration;

mod ser;
pub use ser::to_value;

#[cfg(feature = "json")]
mod json;
#[cfg(test)]
mod testing;

use magic::FromContext;

Expand Down Expand Up @@ -173,11 +173,16 @@ impl TryFrom<&str> for Program {
mod tests {
use crate::context::Context;
use crate::objects::{ResolveResult, Value};
use crate::testing::test_script;
use crate::{ExecutionError, Program};
use std::collections::HashMap;
use std::convert::TryInto;

/// Tests the provided script and returns the result. An optional context can be provided.
pub(crate) fn test_script(script: &str, ctx: Option<Context>) -> ResolveResult {
let program = Program::compile(script).unwrap();
program.execute(&ctx.unwrap_or_default())
}

#[test]
fn parse() {
Program::compile("1 + 1").unwrap();
Expand Down
38 changes: 25 additions & 13 deletions interpreter/src/objects.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
use crate::context::Context;
use crate::functions::FunctionContext;
use crate::ser::SerializationError;
use crate::ExecutionError::NoSuchKey;
use crate::{to_value, ExecutionError};
use cel_parser::{ArithmeticOp, Atom, Expression, Member, RelationOp, UnaryOp};
use core::ops;
use serde::{Serialize, Serializer};
use crate::ExecutionError;
use cel_parser::ast::*;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::convert::{Infallible, TryFrom, TryInto};
use std::fmt::{Display, Formatter};
use std::ops;
use std::sync::Arc;

#[derive(Debug, PartialEq, Clone)]
Expand Down Expand Up @@ -84,10 +81,10 @@ impl From<u64> for Key {
}
}

impl Serialize for Key {
impl serde::Serialize for Key {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
S: serde::Serializer,
{
match self {
Key::Int(v) => v.serialize(serializer),
Expand Down Expand Up @@ -143,13 +140,12 @@ pub trait TryIntoValue {
fn try_into_value(self) -> Result<Value, Self::Error>;
}

impl<T: Serialize> TryIntoValue for T {
type Error = SerializationError;
impl<T: serde::Serialize> TryIntoValue for T {
type Error = crate::ser::SerializationError;
fn try_into_value(self) -> Result<Value, Self::Error> {
to_value(self)
crate::ser::to_value(self)
}
}

impl TryIntoValue for Value {
type Error = Infallible;
fn try_into_value(self) -> Result<Value, Self::Error> {
Expand Down Expand Up @@ -629,7 +625,7 @@ impl<'a> Value {
// give priority to the property. Maybe we can implement lookahead
// to see if the next token is a function call?
match (child, ctx.has_function(&***name)) {
(None, false) => NoSuchKey(name.clone()).into(),
(None, false) => ExecutionError::NoSuchKey(name.clone()).into(),
(Some(child), _) => child.into(),
(None, true) => Value::Function(name.clone(), Some(self.into())).into(),
}
Expand Down Expand Up @@ -960,4 +956,20 @@ mod tests {
let result = program.execute(&context);
assert_eq!(result.unwrap(), Value::Null);
}

#[test]
fn reference_to_value() {
let test = "example".to_string();
let direct: Value = test.as_str().into();
assert_eq!(direct, Value::String(Arc::new(String::from("example"))));

let vec = vec![test.as_str()];
let indirect: Value = vec.into();
assert_eq!(
indirect,
Value::List(Arc::new(vec![Value::String(Arc::new(String::from(
"example"
)))]))
);
}
}
9 changes: 0 additions & 9 deletions interpreter/src/testing.rs

This file was deleted.

0 comments on commit 564e3fc

Please sign in to comment.