Skip to main content

Crate yo_derive

Crate yo_derive 

Source
Expand description

#[derive(Yo)], which writes a type’s shape, its document encoding and the indexes it declares (15 sections 3 and 4).

#[derive(Yo)]
struct Order {
    #[yo(id)]
    id: u64,
    #[yo(index)]
    status: String,
    #[yo(ordered)]
    total: f64,
    #[yo(array)]
    tags: Vec<String>,
    #[yo(text)]
    note: String,
}

That gives Order three things. A shape, which is the canonical description the collection is created with and every later open is checked against. A document encoding, so a value goes into the store as YOJB without passing through JSON text. And a list of indexes, which the collection declares the first time it is opened, plus a Path constant per indexed field so a query is written Order::STATUS rather than "$.status".

§The words

#[yo(id)] names the field that is the document’s id, and a type needs one to be a document at all. #[yo(index)] asks equality, #[yo(ordered)] asks equality and ranges, #[yo(array)] files the document under every element of a list, and #[yo(text)] files it under every word of a string. They are the four kinds a path index comes in and nothing is invented here.

§Why there are no dependencies

A derive is the one place a library gets to put three crates in everybody’s build graph without being asked, and the usual three are most of what a cold build of a small program costs. What this reads is a struct with named fields, and a field is an attribute, a visibility, a name, a colon and some tokens. The compiler hands that over already split into tokens, so the parser in parse is a few hundred lines and the types themselves are carried straight back out without ever being understood.

The cost of that choice is that the errors here are sentences rather than spans, so a mistake points at the struct rather than at the word. That is the trade, and it is written down rather than discovered.

Derive Macros§

Yo
Write a type’s shape, its document encoding and its indexes.