Skip to content

Commit 09ece43

Browse files
feat: Support adding Durations to Timestamps (with the --chrono flag) (#6)
1 parent ec5c850 commit 09ece43

File tree

4 files changed

+32
-14
lines changed

4 files changed

+32
-14
lines changed

libs/core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ crate-type = ["cdylib"]
99
[dependencies]
1010
napi = { version = "2.12.2", features = ["serde-json"] }
1111
napi-derive = "2.12.2"
12-
cel-interpreter = { path = "cel-rust/interpreter" }
12+
cel-interpreter = { path = "cel-rust/interpreter", features = ["chrono"] }
1313
serde = { version = "1.0", features = ["derive"] }
1414
serde_json = "1.0"
1515

libs/core/__tests__/cel.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ import { beforeEach, describe, expect, it } from "vitest";
22
import { CelProgram, evaluate } from "../src/index.js";
33

44
describe("evaluate", () => {
5+
it("should add a duration to a timestamp using chrono feature", async () => {
6+
const result = await evaluate(
7+
"timestamp('2023-01-01T00:00:00Z') + duration('1h')",
8+
{},
9+
);
10+
// The expected result is '2023-01-01T01:00:00Z' as an ISO string
11+
expect(result).toBe("2023-01-01T01:00:00+00:00");
12+
});
513
it("should evaluate a simple expression", async () => {
614
const result = await evaluate("size(message) > 5", {
715
message: "Hello World",

libs/core/project.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
"name": "@kevinmichaelchen/cel-typescript-core",
33
"$schema": "node_modules/nx/schemas/project-schema.json",
44
"targets": {
5+
"build": {
6+
"executor": "nx:noop",
7+
"dependsOn": ["build:native", "build:ts"]
8+
},
59
"build:native": {
610
"cache": false,
711
"executor": "nx:run-commands",
@@ -26,10 +30,6 @@
2630
},
2731
"outputs": ["{projectRoot}/dist/**/*"]
2832
},
29-
"build": {
30-
"executor": "nx:noop",
31-
"dependsOn": ["build:native", "build:ts"]
32-
},
3333
"clean": {
3434
"cache": false,
3535
"executor": "nx:run-commands",

libs/core/src/lib.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![deny(clippy::all)]
22

3+
use cel_interpreter::{Context, Program, Value};
34
use napi_derive::napi;
4-
use cel_interpreter::{Program, Context, Value};
55
use serde_json::Value as JsonValue;
66
use std::sync::Arc;
77

@@ -19,8 +19,8 @@ impl CelProgram {
1919

2020
#[napi]
2121
pub fn compile(source: String) -> napi::Result<CelProgram> {
22-
let program = Program::compile(&source)
23-
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
22+
let program =
23+
Program::compile(&source).map_err(|e| napi::Error::from_reason(e.to_string()))?;
2424
Ok(CelProgram { program })
2525
}
2626

@@ -38,12 +38,12 @@ impl CelProgram {
3838
} else {
3939
Value::Null
4040
}
41-
},
41+
}
4242
JsonValue::String(s) => Value::String(Arc::new(s.clone())),
4343
JsonValue::Array(arr) => {
4444
let values: Vec<Value> = arr.iter().map(|v| Self::json_to_cel_value(v)).collect();
4545
Value::List(Arc::new(values))
46-
},
46+
}
4747
JsonValue::Object(map) => {
4848
let mut cel_map = std::collections::HashMap::new();
4949
for (key, value) in map {
@@ -65,27 +65,37 @@ impl CelProgram {
6565
.unwrap_or(JsonValue::Null),
6666
Value::String(s) => JsonValue::String((*s).to_string()),
6767
Value::List(list) => JsonValue::Array(
68-
list.iter().map(|v| Self::cel_to_json_value(v.clone())).collect()
68+
list.iter()
69+
.map(|v| Self::cel_to_json_value(v.clone()))
70+
.collect(),
6971
),
7072
Value::Map(map) => JsonValue::Object(
71-
map.map.iter().map(|(k, v)| (k.to_string(), Self::cel_to_json_value(v.clone()))).collect()
73+
map.map
74+
.iter()
75+
.map(|(k, v)| (k.to_string(), Self::cel_to_json_value(v.clone())))
76+
.collect(),
7277
),
78+
Value::Timestamp(ts) => JsonValue::String(ts.to_rfc3339()),
79+
Value::Duration(dur) => {
80+
JsonValue::Number(serde_json::Number::from(dur.num_nanoseconds().unwrap_or(0)))
81+
}
7382
_ => JsonValue::Null,
7483
}
7584
}
7685

7786
#[napi]
7887
pub fn execute(&self, context: JsonValue) -> napi::Result<JsonValue> {
7988
let mut ctx = Context::default();
80-
89+
8190
if let JsonValue::Object(map) = context {
8291
for (key, value) in map {
8392
let cel_value = Self::json_to_cel_value(&value);
8493
ctx.add_variable_from_value(key, cel_value);
8594
}
8695
}
8796

88-
self.program.execute(&ctx)
97+
self.program
98+
.execute(&ctx)
8999
.map_err(|e| napi::Error::from_reason(e.to_string()))
90100
.map(Self::cel_to_json_value)
91101
}

0 commit comments

Comments
 (0)