extern crate bytes;
extern crate chrono;
extern crate hex;
extern crate itertools;
extern crate num;
extern crate ordered_float;
extern crate peg;
extern crate pretty;
#[cfg(feature = "serde_support")]
extern crate serde;
#[cfg(feature = "serde_support")]
#[macro_use]
extern crate serde_derive;
extern crate uuid;
pub mod depth;
pub use crate::depth::{check_nesting, MAX_NESTING};
pub mod entities;
pub mod intern_set;
pub use crate::intern_set::InternSet;
pub mod matcher;
mod namespaceable_name;
pub mod pretty_print;
pub mod query;
pub mod symbols;
pub mod types;
pub mod utils;
pub mod value_rc;
pub use crate::value_rc::{Cloned, FromRc, ValueRc};
use bytes::Bytes;
pub use chrono::{DateTime, Utc};
use hex::decode;
pub use num::BigInt;
pub use ordered_float::OrderedFloat;
pub use uuid::Uuid;
pub use crate::types::{
FromMicros, FromMillis, Span, SpannedValue, ToMicros, ToMillis, Value, ValueAndSpan,
};
pub use crate::symbols::{Keyword, NamespacedSymbol, PlainSymbol};
use std::collections::{BTreeMap, BTreeSet, LinkedList};
use std::iter::FromIterator;
use chrono::TimeZone;
use crate::entities::*;
use crate::query::FromValue;
pub type ParseError = peg::error::ParseError<peg::str::LineCol>;
enum InItem {
Source(query::SrcVar),
Binding(query::Binding),
}
peg::parser!(grammar grammar() for str {
pub rule nil() -> SpannedValue = "nil" { SpannedValue::Nil }
pub rule nan() -> SpannedValue = "#f" whitespace()+ "NaN" { SpannedValue::Float(OrderedFloat(f64::NAN)) }
pub rule infinity() -> SpannedValue = "#f" whitespace()+ s:$(sign()) "Infinity"
{ SpannedValue::Float(OrderedFloat(if s == "+" { f64::INFINITY } else { f64::NEG_INFINITY })) }
pub rule boolean() -> SpannedValue
= "true" { SpannedValue::Boolean(true) }
/ "false" { SpannedValue::Boolean(false) }
rule digit() = ['0'..='9']
rule alphanumeric() = ['0'..='9' | 'a'..='z' | 'A'..='Z']
rule octaldigit() = ['0'..='7']
rule validbase() = ['3']['0'..='6'] / ['1' | '2']['0'..='9'] / ['2'..='9']
rule hex() = ['0'..='9' | 'a'..='f' | 'A'..='F']
rule sign() = ['+' | '-']
pub rule raw_bigint() -> BigInt = b:$( sign()? digit()+ ) "N"
{ b.parse::<BigInt>().unwrap() }
pub rule raw_octalinteger() -> i64 = "0" i:$( octaldigit()+ )
{ i64::from_str_radix(i, 8).unwrap() }
pub rule raw_hexinteger() -> i64 = "0x" i:$( hex()+ )
{ i64::from_str_radix(i, 16).unwrap() }
pub rule raw_basedinteger() -> i64 = b:$( validbase() ) "r" i:$( alphanumeric()+ )
{ i64::from_str_radix(i, b.parse::<u32>().unwrap()).unwrap() }
pub rule raw_integer() -> i64 = i:$( sign()? digit()+ ) !("." / (['e' | 'E']))
{ i.parse::<i64>().unwrap() }
pub rule raw_float() -> OrderedFloat<f64> = f:$(sign()? digit()+ ("." digit()+)? (['e' | 'E'] sign()? digit()+)?)
{ OrderedFloat(f.parse::<f64>().unwrap()) }
pub rule bigint() -> SpannedValue = v:raw_bigint() { SpannedValue::BigInteger(v) }
pub rule octalinteger() -> SpannedValue = v:raw_octalinteger() { SpannedValue::Integer(v) }
pub rule hexinteger() -> SpannedValue = v:raw_hexinteger() { SpannedValue::Integer(v) }
pub rule basedinteger() -> SpannedValue = v:raw_basedinteger() { SpannedValue::Integer(v) }
pub rule integer() -> SpannedValue = v:raw_integer() { SpannedValue::Integer(v) }
pub rule float() -> SpannedValue = v:raw_float() { SpannedValue::Float(v) }
rule number() -> SpannedValue = ( bigint() / basedinteger() / hexinteger() / octalinteger() / integer() / float() )
rule string_special_char() -> &'input str = "\\" c:$(['\\' | '"' | 'n' | 't' | 'r']) {
match c {
"n" => "\n",
"t" => "\t",
"r" => "\r",
literal => literal,
}
}
rule string_normal_chars() -> &'input str = c:$((!['\"' | '\\'][_])+) { c }
pub rule raw_text() -> String = "\"" t:((string_special_char() / string_normal_chars())*) "\""
{ t.join("") }
pub rule text() -> SpannedValue
= v:raw_text() { SpannedValue::Text(v) }
rule inst_string() -> DateTime<Utc> =
"#inst" whitespace()+ "\"" d:$( ['0'..='9']*<4> "-" ['0'..='2']['0'..='9'] "-" ['0'..='3']['0'..='9']
"T"
['0'..='2']['0'..='9'] ":" ['0'..='5']['0'..='9'] ":" ['0'..='6']['0'..='9']
("." ['0'..='9']+)?
("Z" / (("+" / "-") ['0'..='2']['0'..='9'] ":" ['0'..='5']['0'..='9']))
)
"\"" {?
DateTime::parse_from_rfc3339(d)
.map(|t| t.with_timezone(&Utc))
.map_err(|_| "invalid datetime") }
rule inst_micros() -> DateTime<Utc> =
"#instmicros" whitespace()+ d:$( digit()+ ) {
let micros = d.parse::<i64>().unwrap();
let seconds: i64 = micros / 1_000_000;
let nanos: u32 = ((micros % 1_000_000).unsigned_abs() as u32) * 1000;
Utc.timestamp_opt(seconds, nanos).unwrap()
}
rule inst_millis() -> DateTime<Utc> =
"#instmillis" whitespace()+ d:$( digit()+ ) {
let millis = d.parse::<i64>().unwrap();
let seconds: i64 = millis / 1000;
let nanos: u32 = ((millis % 1000).unsigned_abs() as u32) * 1_000_000;
Utc.timestamp_opt(seconds, nanos).unwrap()
}
rule inst() -> SpannedValue = t:(inst_millis() / inst_micros() / inst_string())
{ SpannedValue::Instant(t) }
rule uuid_string() -> Uuid =
"\"" u:$( ['a'..='f' | '0'..='9']*<8> "-" ['a'..='f' | '0'..='9']*<4> "-" ['a'..='f' | '0'..='9']*<4> "-" ['a'..='f' | '0'..='9']*<4> "-" ['a'..='f' | '0'..='9']*<12> ) "\"" {
Uuid::parse_str(u).expect("this is a valid UUID string")
}
pub rule uuid() -> SpannedValue = "#uuid" whitespace()+ u:uuid_string()
{ SpannedValue::Uuid(u) }
rule byte_buffer() -> Bytes =
u:$( hex()+ ) {
let b = decode(u).expect("this is a valid hex byte string");
Bytes::copy_from_slice(&b)
}
pub rule bytes() -> SpannedValue = "#bytes" whitespace()+ u:byte_buffer()
{ SpannedValue::Bytes(u) }
rule namespace_divider() = "."
rule namespace_separator() = "/"
rule symbol_char_initial() = ['a'..='z' | 'A'..='Z' | '0'..='9' | '*' | '!' | '_' | '?' | '$' | '%' | '&' | '=' | '<' | '>']
rule symbol_char_subsequent() = ['+' | 'a'..='z' | 'A'..='Z' | '0'..='9' | '*' | '!' | '_' | '?' | '$' | '%' | '&' | '=' | '<' | '>' | '-']
rule symbol_namespace() = symbol_char_initial() symbol_char_subsequent()* (namespace_divider() symbol_char_subsequent()+)*
rule symbol_name() = ( symbol_char_initial()+ symbol_char_subsequent()* )
rule sign_symbol_name() = ['+' | '-'] !['0'..='9'] symbol_char_subsequent()*
rule plain_symbol_name() = symbol_name() / "..." / "." / sign_symbol_name() / "/"
rule keyword_prefix() = ":"
pub rule symbol() -> SpannedValue =
ns:( sns:$(symbol_namespace()) namespace_separator() { sns })?
n:$(plain_symbol_name())
{ SpannedValue::from_symbol(ns, n) }
/ expected!("symbol")
pub rule keyword() -> SpannedValue =
keyword_prefix()
ns:( sns:$(symbol_namespace()) namespace_separator() { sns })?
n:$(symbol_name())
{ SpannedValue::from_keyword(ns, n) }
/ expected!("keyword")
pub rule list() -> SpannedValue = "(" __ v:(value())* __ ")"
{ SpannedValue::List(LinkedList::from_iter(v)) }
pub rule vector() -> SpannedValue = "[" __ v:(value())* __ "]"
{ SpannedValue::Vector(v) }
pub rule set() -> SpannedValue = "#{" __ v:(value())* __ "}"
{ SpannedValue::Set(BTreeSet::from_iter(v)) }
pub rule pair() -> (ValueAndSpan, ValueAndSpan) =
k:(value()) v:(value()) {
(k, v)
}
pub rule map() -> SpannedValue = "{" __ v:(pair())* __ "}"
{ SpannedValue::Map(BTreeMap::from_iter(v)) }
pub rule value() -> ValueAndSpan =
__ start:position!() v:(nil() / nan() / infinity() / boolean() / number() / inst() / uuid() / bytes() / text() / keyword() / symbol() / list() / vector() / map() / set() ) end:position!() __ {
ValueAndSpan {
inner: v,
span: Span::new(start, end)
}
}
/ expected!("value")
rule atom() -> ValueAndSpan
= v:value() {? if v.is_atom() { Ok(v) } else { Err("expected atom") } }
rule whitespace() = quiet!{[' ' | '\r' | '\n' | '\t' | ',']}
rule comment() = quiet!{";" (!['\r' | '\n'][_])* ['\r' | '\n']?}
rule __() = (whitespace() / comment())*
pub rule op() -> OpType
= ":db/add" { OpType::Add }
/ ":db/retract" { OpType::Retract }
rule builtin_tx_fn() -> BuiltinTxFn
= ":db.fn/cas" { BuiltinTxFn::Cas }
/ ":db/cas" { BuiltinTxFn::Cas }
/ ":db.fn/retractEntity" { BuiltinTxFn::RetractEntity }
/ ":db/retractEntity" { BuiltinTxFn::RetractEntity }
rule raw_keyword() -> Keyword =
keyword_prefix()
ns:( sns:$(symbol_namespace()) namespace_separator() { sns })?
n:$(symbol_name()) {
match ns {
Some(ns) => Keyword::namespaced(ns, n),
None => Keyword::plain(n),
}
}
/ expected!("keyword")
rule raw_forward_keyword() -> Keyword
= v:raw_keyword() {? if v.is_forward() { Ok(v) } else { Err("expected :forward or :forward/keyword") } }
rule raw_backward_keyword() -> Keyword
= v:raw_keyword() {? if v.is_backward() { Ok(v) } else { Err("expected :_backward or :backward/_keyword") } }
rule raw_namespaced_keyword() -> Keyword
= keyword_prefix() ns:$(symbol_namespace()) namespace_separator() n:$(symbol_name()) { Keyword::namespaced(ns, n) }
/ expected!("namespaced keyword")
rule raw_forward_namespaced_keyword() -> Keyword
= v:raw_namespaced_keyword() {? if v.is_forward() { Ok(v) } else { Err("expected namespaced :forward/keyword") } }
rule raw_backward_namespaced_keyword() -> Keyword
= v:raw_namespaced_keyword() {? if v.is_backward() { Ok(v) } else { Err("expected namespaced :backward/_keyword") } }
rule entid() -> EntidOrIdent
= v:( raw_basedinteger() / raw_hexinteger() / raw_octalinteger() / raw_integer() ) { EntidOrIdent::Entid(v) }
/ v:raw_namespaced_keyword() { EntidOrIdent::Ident(v) }
/ expected!("entid")
rule forward_entid() -> EntidOrIdent
= v:( raw_basedinteger() / raw_hexinteger() / raw_octalinteger() / raw_integer() ) { EntidOrIdent::Entid(v) }
/ v:raw_forward_namespaced_keyword() { EntidOrIdent::Ident(v) }
/ expected!("forward entid")
rule backward_entid() -> EntidOrIdent
= v:raw_backward_namespaced_keyword() { EntidOrIdent::Ident(v.to_reversed()) }
/ expected!("backward entid")
rule lookup_ref() -> LookupRef<ValueAndSpan>
= "(" __ "lookup-ref" __ a:(entid()) __ v:(value()) __ ")" { LookupRef { a: AttributePlace::Entid(a), v } }
/ expected!("lookup-ref")
rule vector_lookup_ref() -> LookupRef<ValueAndSpan>
= "[" __ a:(raw_namespaced_keyword()) __ v:(atom()) __ "]" { LookupRef { a: AttributePlace::Entid(EntidOrIdent::Ident(a)), v } }
rule tx_function() -> TxFunction
= "(" __ n:$(symbol_name()) __ ")" { TxFunction { op: PlainSymbol::plain(n) } }
rule entity_place() -> EntityPlace<ValueAndSpan>
= v:raw_text() { EntityPlace::TempId(TempId::External(v).into()) }
/ v:entid() { EntityPlace::Entid(v) }
/ v:lookup_ref() { EntityPlace::LookupRef(v) }
/ v:vector_lookup_ref() { EntityPlace::LookupRef(v) }
/ v:tx_function() { EntityPlace::TxFunction(v) }
rule value_place_pair() -> (EntidOrIdent, ValuePlace<ValueAndSpan>)
= k:(entid()) __ v:(value_place()) { (k, v) }
rule map_notation() -> MapNotation<ValueAndSpan>
= "{" __ kvs:(value_place_pair()*) __ "}" { kvs.into_iter().collect() }
rule value_place() -> ValuePlace<ValueAndSpan>
= __ v:lookup_ref() __ { ValuePlace::LookupRef(v) }
/ __ v:tx_function() __ { ValuePlace::TxFunction(v) }
/ __ "[" __ vs:(value_place()*) __ "]" __ { ValuePlace::Vector(vs) }
/ __ v:map_notation() __ { ValuePlace::MapNotation(v) }
/ __ v:atom() __ { ValuePlace::Atom(v) }
pub rule entity() -> Entity<ValueAndSpan>
= __ "[" __ fun:(builtin_tx_fn()) __ args:(value_place()*) __ "]" __ { Entity::TxFunction { fun, args } }
/ __ "[" __ op:(op()) __ e:(entity_place()) __ a:(forward_entid()) __ v:(value_place()) __ "]" __ { Entity::AddOrRetract { op, e, a: AttributePlace::Entid(a), v } }
/ __ "[" __ op:(op()) __ e:(value_place()) __ a:(backward_entid()) __ v:(entity_place()) __ "]" __ { Entity::AddOrRetract { op, e: v, a: AttributePlace::Entid(a), v: e } }
/ __ map:map_notation() __ { Entity::MapNotation(map) }
/ expected!("entity")
pub rule entities() -> Vec<Entity<ValueAndSpan>>
= __ "[" __ es:(entity()*) __ "]" __ { es }
rule query_function() -> query::QueryFunction
= __ n:$(symbol_name() / "+" / "-" / "/") __ {? query::QueryFunction::from_symbol(&PlainSymbol::plain(n)).ok_or("expected query function") }
rule fn_arg() -> query::FnArg
= v:value() {? query::FnArg::from_value(&v).ok_or("expected query function argument") }
/ __ "[" args:fn_arg()+ "]" __ { query::FnArg::Vector(args) }
rule find_elem() -> query::Element
= __ v:variable() __ { query::Element::Variable(v) }
/ __ "(" __ "the" v:variable() ")" __ { query::Element::Corresponding(v) }
/ __ "(" __ "pull" var:variable() patterns:pull_pattern() ")" __ { query::Element::Pull(query::Pull { var, patterns }) }
/ __ "(" func:query_function() args:fn_arg()* ")" __ { query::Element::Aggregate(query::Aggregate { func, args }) }
rule find_spec() -> query::FindSpec
= f:find_elem() "." __ { query::FindSpec::FindScalar(f) }
/ fs:find_elem()+ { query::FindSpec::FindRel(fs) }
/ __ "[" f:find_elem() __ "..." __ "]" __ { query::FindSpec::FindColl(f) }
/ __ "[" fs:find_elem()+ "]" __ { query::FindSpec::FindTuple(fs) }
pub rule pull_pattern() -> Vec<query::PullAttributeSpec>
= __ "[" patterns:pull_attribute()+ "]" __ { patterns.into_iter().flatten().collect() }
rule pull_attribute() -> Vec<query::PullAttributeSpec>
= __ "*" __ { vec![query::PullAttributeSpec::Wildcard] }
/ a:pull_keyword() alias:(":as" __ alias:raw_forward_keyword() __ { alias })? {
vec![query::PullAttributeSpec::Attribute(query::NamedPullAttribute {
alias: alias.map(::std::rc::Rc::new),
..a
})]
}
/ __ "{" es:pull_map_entry()+ "}" __ { es }
rule pull_map_entry() -> query::PullAttributeSpec
= a:pull_keyword() p:pull_pattern() { query::PullAttributeSpec::Nested(a, p) }
rule pull_keyword() -> query::NamedPullAttribute
= __ k:raw_backward_namespaced_keyword() __ {
query::NamedPullAttribute {
attribute: query::PullConcreteAttribute::Ident(::std::rc::Rc::new(k.to_reversed())),
alias: None,
reverse: true,
}
}
/ __ k:raw_forward_namespaced_keyword() __ {
query::NamedPullAttribute {
attribute: query::PullConcreteAttribute::Ident(::std::rc::Rc::new(k)),
alias: None,
reverse: false,
}
}
rule limit() -> query::Limit
= __ v:variable() __ { query::Limit::Variable(v) }
/ __ n:(raw_octalinteger() / raw_hexinteger() / raw_basedinteger() / raw_integer()) __ {?
if n > 0 {
Ok(query::Limit::Fixed(n as u64))
} else {
Err("expected positive integer")
}
}
rule offset() -> query::Offset
= __ v:variable() __ { query::Offset::Variable(v) }
/ __ n:(raw_octalinteger() / raw_hexinteger() / raw_basedinteger() / raw_integer()) __ {?
if n >= 0 {
Ok(query::Offset::Fixed(n as u64))
} else {
Err("expected non-negative integer")
}
}
rule order() -> query::Order
= __ "(" __ "asc" v:variable() ")" __ { query::Order(query::Direction::Ascending, v) }
/ __ "(" __ "desc" v:variable() ")" __ { query::Order(query::Direction::Descending, v) }
/ v:variable() { query::Order(query::Direction::Ascending, v) }
rule pattern_value_place() -> query::PatternValuePlace
= v:value() {? query::PatternValuePlace::from_value(&v).ok_or("expected pattern_value_place") }
rule pattern_non_value_place() -> query::PatternNonValuePlace
= v:value() {? query::PatternNonValuePlace::from_value(&v).ok_or("expected pattern_non_value_place") }
rule pattern() -> query::WhereClause
= __ "["
src:src_var()?
e:pattern_non_value_place()
a:pattern_non_value_place()
v:pattern_value_place()?
tx:pattern_non_value_place()?
added:pattern_non_value_place()?
"]" __
{?
let v = v.unwrap_or(query::PatternValuePlace::Placeholder);
let tx = tx.unwrap_or(query::PatternNonValuePlace::Placeholder);
let added = added.unwrap_or(query::PatternNonValuePlace::Placeholder);
query::Pattern::new(src, e, a, v, tx, added)
.map(query::WhereClause::Pattern)
.ok_or("expected pattern")
}
rule rule_vars() -> BTreeSet<query::Variable>
= vs:variable()+ {?
let given = vs.len();
let set: BTreeSet<query::Variable> = vs.into_iter().collect();
if given != set.len() {
Err("expected unique variables")
} else {
Ok(set)
}
}
rule or_pattern_clause() -> query::OrWhereClause
= clause:where_clause() { query::OrWhereClause::Clause(clause) }
rule or_and_clause() -> query::OrWhereClause
= __ "(" __ "and" clauses:where_clause()+ ")" __ { query::OrWhereClause::And(clauses) }
rule or_where_clause() -> query::OrWhereClause
= or_pattern_clause()
/ or_and_clause()
rule or_clause() -> query::WhereClause
= __ "(" __ "or" clauses:or_where_clause()+ ")" __ {
query::WhereClause::OrJoin(query::OrJoin::new(query::UnifyVars::Implicit, clauses))
}
rule or_join_clause() -> query::WhereClause
= __ "(" __ "or-join" __ "[" vars:rule_vars() "]" clauses:or_where_clause()+ ")" __ {
query::WhereClause::OrJoin(query::OrJoin::new(query::UnifyVars::Explicit(vars), clauses))
}
rule not_clause() -> query::WhereClause
= __ "(" __ "not" clauses:where_clause()+ ")" __ {
query::WhereClause::NotJoin(query::NotJoin::new(query::UnifyVars::Implicit, clauses))
}
rule not_join_clause() -> query::WhereClause
= __ "(" __ "not-join" __ "[" vars:rule_vars() "]" clauses:where_clause()+ ")" __ {
query::WhereClause::NotJoin(query::NotJoin::new(query::UnifyVars::Explicit(vars), clauses))
}
rule type_annotation() -> query::WhereClause
= __ "[" __ "(" __ "type" var:variable() __ ty:raw_keyword() __ ")" __ "]" __ {
query::WhereClause::TypeAnnotation(
query::TypeAnnotation {
value_type: ty,
variable: var,
})
}
rule pred() -> query::WhereClause
= __ "[" __ "(" func:query_function() args:fn_arg()* ")" __ "]" __ {
query::WhereClause::Pred(
query::Predicate {
operator: func.0,
args,
})
}
pub rule where_fn() -> query::WhereClause
= __ "[" __ "(" func:query_function() args:fn_arg()* ")" __ binding:binding() "]" __ {
query::WhereClause::WhereFn(
query::WhereFn {
operator: func.0,
args,
binding,
})
}
rule where_clause() -> query::WhereClause
= pattern()
/ or_join_clause()
/ or_clause()
/ not_join_clause()
/ not_clause()
/ type_annotation()
/ pred()
/ where_fn()
/ rule_invocation()
rule rule_invocation() -> query::WhereClause
= __ "(" __ n:$(symbol_name()) args:fn_arg()+ ")" __ {?
let name = n.to_string();
if name == "or" || name == "not" || name == "and"
|| name == "or-join" || name == "not-join"
|| name == "type" || name == "fulltext" || name == "ground"
|| name == "get-else" || name == "missing?" {
Err("not a rule invocation")
} else {
Ok(query::WhereClause::RuleExpr(query::RuleInvocation {
name: PlainSymbol::plain(&name),
args,
}))
}
}
rule rule_head() -> query::RuleInvocation
= __ "(" __ n:$(symbol_name()) args:fn_arg()+ ")" __ {
query::RuleInvocation {
name: PlainSymbol::plain(n),
args,
}
}
rule rule_clause() -> query::RuleClause
= __ "[" head:rule_head() body:where_clause()+ "]" __ {
query::RuleClause { head, body }
}
rule rule_definitions() -> Vec<query::Rule>
= __ "[" clauses:rule_clause()+ "]" __ {
let mut rule_map: std::collections::BTreeMap<String, Vec<query::RuleClause>> =
std::collections::BTreeMap::new();
for clause in clauses {
let name = clause.head.name.0.clone();
rule_map.entry(name).or_default().push(clause);
}
rule_map.into_iter().map(|(name, clauses)| {
query::Rule {
name: PlainSymbol::plain(&name),
clauses,
}
}).collect()
}
rule query_part() -> Vec<query::QueryPart>
= __ ":find" fs:find_spec() { vec![query::QueryPart::FindSpec(fs)] }
/ __ ":in" parts:in_clause() { parts }
/ __ ":limit" l:limit() { vec![query::QueryPart::Limit(l)] }
/ __ ":offset" o:offset() { vec![query::QueryPart::Offset(o)] }
/ __ ":order" os:order()+ { vec![query::QueryPart::Order(os)] }
/ __ ":where" ws:where_clause()+ { vec![query::QueryPart::WhereClauses(ws)] }
/ __ ":rules" rules:rule_definitions() { vec![query::QueryPart::Rules(rules)] }
/ __ ":with" rules:rule_definitions() { vec![query::QueryPart::Rules(rules)] }
/ __ ":with" with_vars:variable()+ { vec![query::QueryPart::WithVars(with_vars)] }
/ __ ":distinct" { vec![query::QueryPart::Distinct] }
rule in_clause() -> Vec<query::QueryPart>
= items:in_item()+ {
let mut sources = Vec::new();
let mut bindings = Vec::new();
for item in items {
match item {
InItem::Source(s) => sources.push(s),
InItem::Binding(b) => bindings.push(b),
}
}
let mut parts = Vec::new();
if !sources.is_empty() { parts.push(query::QueryPart::InSources(sources)); }
parts.push(query::QueryPart::InBindings(bindings));
parts
}
rule in_item() -> InItem
= __ &"$" s:src_var() { InItem::Source(s) }
/ b:binding() { InItem::Binding(b) }
pub rule parse_query() -> query::ParsedQuery
= __ "[" qps:query_part()+ "]" __ {? query::ParsedQuery::from_parts(qps.into_iter().flatten().collect()) }
rule variable() -> query::Variable
= v:value() {? query::Variable::from_value(&v).ok_or("expected variable") }
rule src_var() -> query::SrcVar
= v:value() {? query::SrcVar::from_value(&v).ok_or("expected src_var") }
rule variable_or_placeholder() -> query::VariableOrPlaceholder
= v:variable() { query::VariableOrPlaceholder::Variable(v) }
/ __ "_" __ { query::VariableOrPlaceholder::Placeholder }
rule binding() -> query::Binding
= __ "[" __ "[" vs:variable_or_placeholder()+ "]" __ "]" __ { query::Binding::BindRel(vs) }
/ __ "[" v:variable() "..." __ "]" __ { query::Binding::BindColl(v) }
/ __ "[" vs:variable_or_placeholder()+ "]" __ { query::Binding::BindTuple(vs) }
/ v:variable() { query::Binding::BindScalar(v) }
});
pub mod parse {
use super::*;
pub fn nil(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::nil(input)
}
pub fn nan(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::nan(input)
}
pub fn infinity(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::infinity(input)
}
pub fn boolean(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::boolean(input)
}
pub fn raw_bigint(input: &str) -> Result<BigInt, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::raw_bigint(input)
}
pub fn raw_octalinteger(input: &str) -> Result<i64, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::raw_octalinteger(input)
}
pub fn raw_hexinteger(input: &str) -> Result<i64, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::raw_hexinteger(input)
}
pub fn raw_basedinteger(input: &str) -> Result<i64, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::raw_basedinteger(input)
}
pub fn raw_integer(input: &str) -> Result<i64, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::raw_integer(input)
}
pub fn raw_float(input: &str) -> Result<OrderedFloat<f64>, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::raw_float(input)
}
pub fn bigint(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::bigint(input)
}
pub fn octalinteger(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::octalinteger(input)
}
pub fn hexinteger(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::hexinteger(input)
}
pub fn basedinteger(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::basedinteger(input)
}
pub fn integer(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::integer(input)
}
pub fn float(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::float(input)
}
pub fn raw_text(input: &str) -> Result<String, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::raw_text(input)
}
pub fn text(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::text(input)
}
pub fn uuid(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::uuid(input)
}
pub fn bytes(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::bytes(input)
}
pub fn symbol(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::symbol(input)
}
pub fn keyword(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::keyword(input)
}
pub fn list(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::list(input)
}
pub fn vector(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::vector(input)
}
pub fn set(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::set(input)
}
pub fn pair(input: &str) -> Result<(ValueAndSpan, ValueAndSpan), ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::pair(input)
}
pub fn map(input: &str) -> Result<SpannedValue, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::map(input)
}
pub fn value(input: &str) -> Result<ValueAndSpan, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::value(input)
}
pub fn op(input: &str) -> Result<OpType, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::op(input)
}
pub fn entity(input: &str) -> Result<Entity<ValueAndSpan>, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::entity(input)
}
pub fn entities(input: &str) -> Result<Vec<Entity<ValueAndSpan>>, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::entities(input)
}
pub fn where_fn(input: &str) -> Result<crate::query::WhereClause, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::where_fn(input)
}
pub fn parse_query(input: &str) -> Result<crate::query::ParsedQuery, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::parse_query(input)
}
pub fn pull_pattern(input: &str) -> Result<Vec<crate::query::PullAttributeSpec>, ParseError> {
crate::depth::check_nesting(input, crate::depth::MAX_NESTING)?;
grammar::pull_pattern(input)
}
}