rest-sql
Parse and validate RSQL / FIQL filter queries into a typed AST, or build filters programmatically — then hand the result to a backend driver.
name=like=Chris*;year=gt=1990;genre=in=(Drama,Thriller)
This crate is pure and WASM-compatible — it has no I/O and no backend dependency.
For compiling to SQL/MongoDB/SurrealQL, see rest-sql-drivers.
Parse a query string
use RestSql;
let rsql = new?;
Build programmatically
Use the filter module when the query comes from code rather than a string:
use ;
use Ast;
// Simple composition
let ast = ilike & gte;
let rsql = from_ast?;
// Conditional construction — fields are optional at runtime
let nodes: =
.into_iter
.flatten
.collect;
let rsql = from_ast?;
from_ast runs the same validation as new — operator/value compatibility, =between= arity, etc.
BitAnd / BitOr combinators
& and | operators flatten adjacent nodes of the same type:
let a = eq & gte; // And([eq, gte])
let b = eq & eq; // And([eq, eq])
let merged = a & b; // And([eq, gte, eq, eq]) — flat, not nested
Operators
| Short | Long | Meaning |
|---|---|---|
== |
=eq= |
Equal |
!= |
=neq= |
Not equal |
< |
=lt= |
Less than |
<= |
=le= |
Less than or equal |
> |
=gt= |
Greater than |
>= |
=ge= |
Greater than or equal |
=in= |
In list | |
=out= |
Not in list | |
=between= |
Range (inclusive) | |
=null= |
Null / absent | |
=notnull= |
Not null / present | |
=like= |
Pattern (* = any chars, _ = one char) |
|
=ilike= |
Case-insensitive pattern |
Logical connectors: ; = AND, , = OR, (...) = grouping.
Value types recognized at parse time: String, Integer, Float, Boolean, Null, Date (YYYY-MM-DD), DateTime (YYYY-MM-DDTHH:MM:SSZ).
Field allowlisting
Reject queries that reference undeclared fields — important when filters come from user input:
// Explicit list
let rsql = new_for_fields?;
// → Err: field 'secret' is not allowed
// Derive from a serde struct (feature `serde`)
let rsql = ?;
Field mapping
FieldMapper renames logical field names before the AST reaches a driver. Useful for JSONB columns, table aliases, or any naming mismatch:
use ;
use Cow;
;
let rsql = new?.map_fields;
// AST field is now "f.title"
Consumer pattern
The idiomatic way to convert your query structs into a RestSql:
use ;
Feature flags
| Feature | Default | Description |
|---|---|---|
serde |
off | Enables RestSql::new_for::<T>() — field allowlist from #[derive(Deserialize)] |
License
MIT — see LICENSE.
Full documentation and examples: github.com/dohrm/rest-sql.