Skip to main content

Crate oql

Crate oql 

Source
Expand description

§oql; Readable query syntax for Rust iterators

oql is a macro that translates a declarative query syntax into plain Rust iterator chains at compile time. The macro disappears in release builds; the generated code is an ordinary iterator chain.

use oql::oql;

let numbers = vec![1, 2, 3, 4, 5, 6];
let squared_evens: Vec<i32> = oql! {
    from x in numbers
    where x % 2 == 0
    select x * x
}.collect();

assert_eq!(squared_evens, vec![4, 16, 36]);

The macro returns an Iterator. The caller decides what to do with it: .collect(), .sum(), .take(10).collect(), .for_each(...), and so on. For simple queries the generated code is indistinguishable from a hand-written .filter(...).map(...) chain. For complex queries (joins with sorts and projections) the expansion carries some structural overhead, measured in the crate’s benchmark at roughly 1.07× the cost of the equivalent handwritten pipeline. See the Performance section in the repository README for details.

§Clauses

ClauseMeaning
from x in sourceStarts the query; expands to source.into_iter(), so any IntoIterator is accepted
let name = exprAdds a per-element binding; expr is re-evaluated for each element and can reference the range variable and prior bindings
where condFilters elements
orderby keySorts ascending
orderby key descSorts descending
join y in src on a == bInner equality join (hash-join under the hood)
join y in src on a == b into gGroup-join: g is a Vec<Y> of matches (empty if none)
group elem by key into gGroup elements by key; g.key and g.items downstream
select exprProjects to the output type

from and select are mandatory. Everything else is optional and may appear multiple times in any order. Clause order equals execution order, so the pipeline reads linearly and behaves exactly like a hand-written iterator chain would.

Macros§

oql
See the crate-level documentation of oql.