Thanks to visit codestin.com
Credit goes to github.com

Skip to content

sunsided/decypher

 
 

decypher

A Rust parser for the Cypher® property graph language, based on the openCypher specification.

This project is independent and is not affiliated with, endorsed by, or sponsored by Neo4j, Inc. Cypher® and Neo4j® are registered trademarks of Neo4j, Inc.

Cypher crate hero picture

decypher provides a typed AST for Cypher® and openCypher queries, built on a hand-written error-resilient rowan parser derived from the openCypher EBNF specification.

Note: This project is a fork and complete re-implementation of the original pest-based parser by Austin Poor. The parser has been rewritten from the ground up using rowan instead of pest.

Quick Start

Add to your Cargo.toml:

[dependencies]
decypher = "0.2"
use decypher::parse;

let query = parse("MATCH (n:Person) WHERE n.age > 18 RETURN n.name;").unwrap();
println!("{:#?}", query);

Features

  • Typed AST — Every Cypher construct maps to a Rust enum or struct with full type safety.
  • Source spans — Every AST node carries a Span { start, end } (byte offsets into the input) for diagnostics.
  • Ergonomic errorsCypherError with syntax, AST build, and unsupported-production variants via thiserror.
  • Cypher emission — The ToCypher trait renders any AST node back into valid openCypher text, enabling round-trips (parse → ast → to_cypher → parse).
  • serde support — Optional serde feature for Serialize/Deserialize derives on all AST nodes.
  • Typed CST (unstable) — A rust-analyzer-style typed wrapper layer over a lossless rowan CST, available under decypher::cst. Each CST node (SourceFile, MatchClause, Expression, …) exposes typed accessor methods instead of raw SyntaxKind matches. This is what the public parse() function uses internally.

Typed CST example

use decypher::cst::{parse, AstNode, BinOp, Expression};

let result = parse("MATCH (n:Person) WHERE n.age > 18 RETURN n.name");
let source = result.tree();

for stmt in source.statements() {
    for clause in stmt.clauses() {
        // use pattern matching on the Clause enum
    }
}

Emitting Cypher

The ToCypher trait converts AST nodes back into openCypher text. This is useful for query rewriting, formatting, and round-trip testing.

use decypher::ast::ToCypher;
use decypher::parse;

let query = parse("MATCH (n:Person) WHERE n.age > 18 RETURN n.name;").unwrap();
let cypher = query.to_cypher();
check!(cypher.contains("MATCH"));

Stability

The AST is unstable until 0.2.0. Grammar completeness is tracked against the openCypher EBNF. Unsupported grammar productions return CypherError::Unsupported rather than panicking.

The ToCypher trait and round-trip guarantees are also unstable — formatting output may change between releases until 0.2.0.

Project Structure

  • src/parser/ — Hand-written error-resilient rowan parser (grammar + lexer).
  • src/syntax/ — Rowan language definition and typed CST wrappers.
  • src/ast/ — Typed AST node definitions and the CST → AST lowering logic (src/ast/build_cst/).
  • src/error.rsCypherError and Span types.
  • src/lib.rs — Public API (parse, Query, CypherError).
  • assets/cypher.ebnf — OpenCypher grammar definition from the openCypher site.

Contributing

Contributions of any size are welcome! Please feel free to submit issues or PRs.

License

This library code is triple-licensed under EUPL-1.2, MIT, or Apache-2.0; choose whichever suits your use case best.

Cypher® and Neo4j® are registered trademarks of Neo4j, Inc.

About

A Rust parser for the Cypher® property graph language, based on the openCypher specification.

Topics

Resources

License

Apache-2.0 and 2 other licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
EUPL-1.2
LICENSE-EUPL
MIT
LICENSE-MIT

Stars

Watchers

Forks

Contributors

Languages

  • Rust 97.8%
  • Cypher 2.0%
  • Shell 0.2%