#expr #context #environment #language #env #arg #serde

expr-lang

Implementation of expr language in Rust

11 releases

new 0.3.0 Mar 18, 2025
0.2.2 Jan 5, 2025
0.2.1 Nov 29, 2024
0.1.6 Nov 25, 2024

#4 in #expr

Download history 1313/week @ 2024-11-29 1261/week @ 2024-12-06 1797/week @ 2024-12-13 1124/week @ 2024-12-20 796/week @ 2024-12-27 1125/week @ 2025-01-03 992/week @ 2025-01-10 728/week @ 2025-01-17 1042/week @ 2025-01-24 843/week @ 2025-01-31 752/week @ 2025-02-07 826/week @ 2025-02-14 766/week @ 2025-02-21 483/week @ 2025-02-28 366/week @ 2025-03-07 617/week @ 2025-03-14

2,303 downloads per month
Used in mise

MIT license

83KB
2K SLoC

expr-lang

Implementation of expr in rust.

Usage

use expr::{Context, Environment, self};

fn main() {
    let mut ctx = Context::default();
    ctx.insert("two".to_string(), 2);

    let three: i64 = expr::eval("1 + two", &ctx).unwrap().as_number().unwrap();
    assert_eq!(three, 3);

    let mut env = Environment::new();
    env.add_function("add", |c| {
        let mut sum = 0;
        for arg in c.args {
            sum += arg.as_number().unwrap();
        }
        Ok(sum.into())
    });

    let six: i64 = env.eval("add(1, two, 3)", &ctx).unwrap().as_number().unwrap();
    assert_eq!(six, 6);
}

Serde integration

Converting expr values to/from rust types

[dependencies]
expr = { version = "0.2", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
use expr::{Value, to_value, from_value};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Foo {
    a: i64,
    b: String,
}

fn main() {
    let foo = Foo {
        a: 1,
        b: "hello".to_string(),
    };

    let value: Value = to_value(&foo).unwrap();
    assert_eq!(value, Value::Map(IndexMap::from([
        ("a".to_string(), Value::Number(1)),
    ])));
    assert_eq!(from_value::<Foo>(value).unwrap(), foo);
}

Converting expr values to/from serial data

[dependencies]
expr = { version = "0.2", features = ["serde"] }
serde_json = "1.0"
use expr::Value;
use serde_json::{from_str, to_string};

fn main() {
    let json = r#"{
        "a": 1,
        "b": "hello"
    }"#;

    let value: Value = from_str(json).unwrap();
    assert_eq!(value, Value::Map(IndexMap::from([
        ("a".to_string(), Value::Number(1)),
    ])));
    assert_eq!(to_string(&value).unwrap(), r#"{\"a\":1,\"b\":\"hello\"}"#);
}

Dependencies

~5–7MB
~129K SLoC