use std::fmt;
use super::segment::QuerySegment;
use crate::node::LocatedNode;
use crate::path::NormalizedPath;
use crate::spec::function::FunctionRegistry;
use crate::VariantValue;
mod sealed {
use super::Query;
use crate::spec::segment::QuerySegment;
use crate::spec::segment::Segment;
use crate::spec::selector::filter::Filter;
use crate::spec::selector::index::Index;
use crate::spec::selector::name::Name;
use crate::spec::selector::slice::Slice;
use crate::spec::selector::Selector;
pub trait Sealed {}
impl Sealed for Query {}
impl Sealed for QuerySegment {}
impl Sealed for Segment {}
impl Sealed for Slice {}
impl Sealed for Name {}
impl Sealed for Selector {}
impl Sealed for Index {}
impl Sealed for Filter {}
}
pub trait Queryable: sealed::Sealed {
fn query<'b, T: VariantValue, Registry: FunctionRegistry<Value = T>>(
&self,
current: &'b T,
root: &'b T,
registry: &Registry,
) -> Vec<&'b T>;
fn query_located<'b, T: VariantValue, Registry: FunctionRegistry<Value = T>>(
&self,
current: &'b T,
root: &'b T,
registry: &Registry,
parent: NormalizedPath<'b>,
) -> Vec<LocatedNode<'b, T>>;
}
#[derive(Debug, Clone, Default)]
pub struct Query {
pub kind: QueryKind,
pub segments: Vec<QuerySegment>,
}
impl Query {
pub fn is_singular(&self) -> bool {
for s in &self.segments {
if s.is_descendent() {
return false;
}
if !s.segment.is_singular() {
return false;
}
}
true
}
}
impl fmt::Display for Query {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
QueryKind::Root => write!(f, "$")?,
QueryKind::Current => write!(f, "@")?,
}
for s in &self.segments {
write!(f, "{s}")?;
}
Ok(())
}
}
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub enum QueryKind {
#[default]
Root,
Current,
}
impl Queryable for Query {
fn query<'b, T: VariantValue, Registry: FunctionRegistry<Value = T>>(
&self,
current: &'b T,
root: &'b T,
registry: &Registry,
) -> Vec<&'b T> {
let mut result = match self.kind {
QueryKind::Root => vec![root],
QueryKind::Current => vec![current],
};
for segment in &self.segments {
let mut r = Vec::new();
for node in result {
r.append(&mut segment.query(node, root, registry));
}
result = r;
}
result
}
fn query_located<'b, T: VariantValue, Registry: FunctionRegistry<Value = T>>(
&self,
current: &'b T,
root: &'b T,
registry: &Registry,
parent: NormalizedPath<'b>,
) -> Vec<LocatedNode<'b, T>> {
let mut result = match self.kind {
QueryKind::Current => vec![LocatedNode::new(parent, current)],
QueryKind::Root => vec![LocatedNode::new(Default::default(), root)],
};
for s in &self.segments {
let mut r = vec![];
for n in result {
let loc = n.location();
let node = n.node();
r.append(&mut s.query_located(node, root, registry, loc.clone()));
}
result = r;
}
result
}
}