z157

Crates.ioz157
lib.rsz157
version2.0.1
created_at2024-12-17 20:20:52.430272+00
updated_at2025-05-10 20:08:21.141718+00
descriptionParser for fields filtering according to Zalando's RESTful API guideline #157
homepage
repositoryhttps://github.com/glennib/z157
max_upload_size
id1486717
size59,694
Glenn Bitar (glennib)

documentation

README

z157

Crates.io docs.rs (with version)

Parser for the field filter defined in Zalando's RESTful API and Event guideline #157.

When would I need this?

If your HTTP service accepts a query parameter that lets the caller specify which fields they would like, this crate helps you parse such a string.

GET http://localhost/users/0001?fields=(age,address(street,city))

The value of the fields query parameter is parsed into a tree of field names.

Example

An example program is found in the examples/ directory. You can run it like this:

cargo run --example example -- '-(name,bio(height_cm),last_seen)'

A more simple example is shown below:

use z157::Tree;

fn main() {
    // Select fields to include
    let tree = Tree::parse(
        "(name,bio(height(meters,centimeters),age))",
    )
    .unwrap();
    
    assert!(!tree.negation());
    let height = tree.index(&["bio", "height"]).unwrap();
    assert!(
        height
            .children()
            .any(|field| field.name() == "meters")
    );
    assert!(
        height
            .children()
            .any(|field| field.name() == "centimeters")
    );
    
    let nested_fields: Vec<_> = tree
        .walk()
        .map(|field| field.path().join("."))
        .collect();
    assert_eq!(
        nested_fields,
        [
            "name",
            "bio",
            "bio.height",
            "bio.height.meters",
            "bio.height.centimeters",
            "bio.age",
        ]
    );
    
    // Select fields to exclude
    let tree = Tree::parse("!(bio)").unwrap();
    
    assert!(tree.negation());
}

The field filter specification

<fields>            ::= [ <negation> ] <fields_struct>
<fields_struct>     ::= "(" <field_items> ")"
<field_items>       ::= <field> [ "," <field_items> ]
<field>             ::= <field_name> | <fields_substruct>
<fields_substruct>  ::= <field_name> <fields_struct>
<field_name>        ::= <dash_letter_digit> [ <field_name> ]
<dash_letter_digit> ::= <dash> | <letter> | <digit>
<dash>              ::= "-" | "_"
<letter>            ::= "A" | ... | "Z" | "a" | ... | "z"
<digit>             ::= "0" | ... | "9"
<negation>          ::= "!"
Commit count: 120

cargo fmt