pub mod filter;
pub mod index;
pub mod name;
pub mod slice;
use std::fmt;
use self::index::Index;
use self::name::Name;
use self::slice::Slice;
use crate::spec::function::FunctionRegistry;
use crate::spec::query::Queryable;
use crate::spec::select_wildcard;
use crate::spec::selector::filter::Filter;
use crate::ConcreteVariantArray;
use crate::ConcreteVariantObject;
use crate::LocatedNode;
use crate::NormalizedPath;
use crate::VariantValue;
#[derive(Debug, Clone)]
pub enum Selector {
Name(Name),
Wildcard,
Index(Index),
ArraySlice(Slice),
Filter(Filter),
}
impl Selector {
pub fn is_singular(&self) -> bool {
matches!(self, Selector::Name(_) | Selector::Index(_))
}
}
impl fmt::Display for Selector {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Selector::Name(name) => write!(f, "{name}"),
Selector::Wildcard => write!(f, "*"),
Selector::Index(index) => write!(f, "{index}"),
Selector::ArraySlice(slice) => write!(f, "{slice}"),
Selector::Filter(filter) => write!(f, "?{filter}"),
}
}
}
impl Queryable for Selector {
fn query<'b, T: VariantValue, Registry: FunctionRegistry<Value = T>>(
&self,
current: &'b T,
root: &'b T,
registry: &Registry,
) -> Vec<&'b T> {
let mut result = Vec::new();
match self {
Selector::Name(name) => result.append(&mut name.query(current, root, registry)),
Selector::Wildcard => select_wildcard(&mut result, current),
Selector::Index(index) => result.append(&mut index.query(current, root, registry)),
Selector::ArraySlice(slice) => result.append(&mut slice.query(current, root, registry)),
Selector::Filter(filter) => result.append(&mut filter.query(current, root, registry)),
}
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>> {
match self {
Selector::Name(name) => name.query_located(current, root, registry, parent),
Selector::Wildcard => {
if let Some(list) = current.as_array() {
list.iter()
.enumerate()
.map(|(i, node)| LocatedNode::new(parent.clone_and_push(i), node))
.collect()
} else if let Some(obj) = current.as_object() {
obj.iter()
.map(|(k, node)| LocatedNode::new(parent.clone_and_push(k), node))
.collect()
} else {
vec![]
}
}
Selector::Index(index) => index.query_located(current, root, registry, parent),
Selector::ArraySlice(slice) => slice.query_located(current, root, registry, parent),
Selector::Filter(filter) => filter.query_located(current, root, registry, parent),
}
}
}