Skip to main content

khive_query/
language.rs

1//! Query language detection and dispatch.
2
3use crate::ast::GqlQuery;
4use crate::error::QueryError;
5use crate::parsers;
6
7/// Which query language the input is written in.
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub enum QueryLanguage {
10    Gql,
11    Sparql,
12}
13
14/// Parse a query string in the given language into a [`GqlQuery`] AST.
15pub fn parse(language: QueryLanguage, input: &str) -> Result<GqlQuery, QueryError> {
16    match language {
17        QueryLanguage::Gql => parsers::gql::parse(input),
18        QueryLanguage::Sparql => parsers::sparql::parse(input),
19    }
20}
21
22/// Auto-detect language and parse (`SELECT` → SPARQL, `MATCH` → GQL, fallback → GQL).
23pub fn parse_auto(input: &str) -> Result<GqlQuery, QueryError> {
24    let trimmed = input.trim();
25    if trimmed
26        .as_bytes()
27        .get(..6)
28        .is_some_and(|p| p.eq_ignore_ascii_case(b"SELECT"))
29    {
30        parsers::sparql::parse(trimmed)
31    } else if trimmed
32        .as_bytes()
33        .get(..5)
34        .is_some_and(|p| p.eq_ignore_ascii_case(b"MATCH"))
35    {
36        parsers::gql::parse(trimmed)
37    } else {
38        // Fall back to GQL to preserve existing behavior for unknown prefixes.
39        parsers::gql::parse(trimmed)
40    }
41}