4 releases

0.2.1 Dec 9, 2024
0.2.0 Dec 9, 2024
0.1.1 Dec 5, 2024
0.1.0 Dec 5, 2024

#919 in Parser implementations

Download history 8/week @ 2024-09-23 227/week @ 2024-12-02 411/week @ 2024-12-09

638 downloads per month
Used in bacon

MIT license

37KB
943 lines

Introspect Query

MIT Latest Version docs Chat on Miaou

IQ (Introspect Query) lets you query standard structs, maps, enums, arrays, tuples, and nested combinations of these, to get deep values with a simple path syntax.

Values jut have to implement serde's Serialize trait. Bot values and queries are dynamic, and can be provided at runtime.

See the IQ trait for all extract functions.

use iq::IQ;
use serde::{ Deserialize, Serialize };

#[derive(Debug, Serialize)]
struct Car {
    pub engine: String,
    pub passengers: Vec<Dog>,
    pub driver: Dog,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Dog {
    pub name: String,
    pub ears: u8,
}

let car = Car {
    engine: "V8".to_string(),
    passengers: vec![
        Dog {
            name: "Roverandom".to_string(),
            ears: 1,
        },
        Dog {
            name: "Laïka".to_string(),
            ears: 2,
        },
    ],
    driver: Dog {
        name: "Rex".to_string(),
        ears: 2,
    },
};

// extract "primitive" values as strings with extract_primitive
assert_eq!(car.extract_primitive("driver.ears").unwrap(), "2");
assert_eq!(car.extract_primitive("driver.name").unwrap(), "Rex");
assert_eq!(car.extract_primitive("passengers.1.name").unwrap(), "Laïka");
assert_eq!(car.extract_primitive("passengers.1"), None); // it's not a primitive

// extract any value as Json with extract_json
assert_eq!(car.extract_json("wrong.path"), None);
assert_eq!(car.extract_json("driver.ears").unwrap(), "2");
assert_eq!(car.extract_json("driver.name").unwrap(), r#""Rex""#);
assert_eq!(
    car.extract_json("passengers.0").unwrap(),
    r#"{"name":"Roverandom","ears":1}"#
);
assert_eq!(car.extract_json("passengers.3"), None);

// extract any deserializable value with extract_value
assert_eq!(car.extract_value("driver.ears").unwrap(), Some(2));
assert_eq!(
    car.extract_value("passengers.1").unwrap(),
    Some(Dog {
        name: "Laïka".to_string(),
        ears: 2
    }),
);

// You don't have to concat tokens if you build the path
assert_eq!(
    car.extract_primitive(vec!["passengers", "0", "ears"])
        .unwrap(),
    "1"
);

// Extract functions are available both on the IQ trait and as standalone functions.
assert_eq!(iq::extract_primitive(&car, "driver.name").unwrap(), "Rex");


// If iq is compied with the "template" feature, you get a mini templating utility
let template = iq::Template::new("{driver.name} drives a {engine} car.");
assert_eq!(template.render(&car), "Rex drives a V8 car.");

IQ also works with enums, maps, and tuples: more tests can be found in libs.rs.

Dependencies

~0.7–2MB
~42K SLoC