Rust
Nexyron is written in Rust, so the Rust interface is the most direct one available: no bridge, no serialisation boundary between your code and the engine.
Opening a database
use nexyron::Database;
fn main() -> nexyron::Result<()> {
let db = Database::open("./business.nexyron")?;
let result = db.query("MATCH (c:Customer) RETURN count(c) AS customers")?;
for row in result.rows() {
let customers: i64 = row.get("customers")?;
println!("{customers}");
}
Ok(())
}
The database closes when it goes out of scope.
Parameters
use nexyron::params;
let result = db.query_with(
"MATCH (c:Customer)-[:BELONGS_TO]->(s:Site {name: $site})
WHERE c.joined_at >= $since
RETURN element_id(c) AS id, c.name AS name",
params! { "site" => "Bergen", "since" => "2026-01-01" },
)?;
Typed rows
Values come back typed, and conversion is explicit so a mismatch is a compile or runtime error rather than a silent surprise:
for row in result.rows() {
let id: String = row.get("id")?;
let name: String = row.get("name")?;
let revenue: f64 = row.get("revenue").unwrap_or(0.0);
println!("{id} {name} {revenue}");
}
Transactions
let tx = db.transaction()?;
tx.query("CREATE (s:Site {name: 'Trondheim'})")?;
tx.query(
"MATCH (c:Customer {name: 'Nora Ellingsen'}), (s:Site {name: 'Trondheim'})
CREATE (c)-[:BELONGS_TO]->(s)",
)?;
tx.commit()?;
Dropping the transaction without committing rolls it back, so an early return on an error leaves nothing half-applied.
Errors
Query failures carry the same guidance the rest of the product gives: what is wrong, the closest valid construct, and where to read about it. Surface that message rather than replacing it with a generic one, because it is usually enough to fix the query without opening the reference.
match db.query(sql) {
Ok(result) => handle(result),
Err(e) => eprintln!("query failed: {e}"),
}
Embedding in an application
One Database is shared across threads. Open it once at startup, hand out
references, and let it close on shutdown. Opening a database per request or per
task is a common and expensive mistake.