Skip to main content

khive_query/
lib.rs

1//! `khive-query` — backend-agnostic GQL/SPARQL parsing and SQL compilation.
2//!
3//! # Two entry points
4//!
5//! ## Explicit language
6//! ```ignore
7//! use khive_query::{QueryLanguage, parse, compile, CompileOptions};
8//!
9//! let ast = parse(QueryLanguage::Gql, "MATCH (a:concept)-[:extends]->(b) RETURN b LIMIT 10")?;
10//! let compiled = compile(&ast, &CompileOptions::default())?;
11//! ```
12//!
13//! ## Auto-detect (SELECT → SPARQL, MATCH → GQL)
14//! ```ignore
15//! use khive_query::parse_auto;
16//!
17//! let ast = parse_auto("SELECT ?a ?b WHERE { ?a :extends ?b . }")?;
18//! ```
19
20pub mod ast;
21pub mod compilers;
22pub mod error;
23pub mod parsers;
24pub mod validate;
25
26pub use ast::{GqlQuery, ReturnItem};
27pub use compilers::sql::{compile, CompileOptions, CompiledQuery};
28pub use error::QueryError;
29pub use validate::{validate, validate_with_warnings, MAX_DEPTH};
30
31/// Which query language the input is written in.
32#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub enum QueryLanguage {
34    Gql,
35    Sparql,
36}
37
38/// Parse a query string in the given language into a [`GqlQuery`] AST.
39pub fn parse(language: QueryLanguage, input: &str) -> Result<GqlQuery, QueryError> {
40    match language {
41        QueryLanguage::Gql => parsers::gql::parse(input),
42        QueryLanguage::Sparql => parsers::sparql::parse(input),
43    }
44}
45
46/// Auto-detect language and parse.
47///
48/// - Starts with `SELECT` → SPARQL
49/// - Starts with `MATCH` → GQL
50pub fn parse_auto(input: &str) -> Result<GqlQuery, QueryError> {
51    let trimmed = input.trim();
52    if trimmed.len() >= 6 && trimmed[..6].eq_ignore_ascii_case("SELECT") {
53        parsers::sparql::parse(trimmed)
54    } else {
55        parsers::gql::parse(trimmed)
56    }
57}