use std::ops::Deref;
use std::ops::DerefMut;
use crate::NodeList;
use crate::VariantValue;
#[derive(Debug)]
pub enum SPathValue<'a, T: VariantValue> {
Nodes(NodeList<'a, T>),
Logical(LogicalType),
Node(&'a T),
Value(T),
Nothing,
}
impl<'a, T: VariantValue> SPathValue<'a, T> {
pub fn into_nodes(self) -> Option<NodesType<'a, T>> {
match self {
SPathValue::Nodes(nodes) => Some(nodes.into()),
_ => None,
}
}
pub fn into_logical(self) -> Option<LogicalType> {
match self {
SPathValue::Logical(logical) => Some(logical),
SPathValue::Nodes(nodes) => Some(LogicalType::from(!nodes.is_empty())),
_ => None,
}
}
pub fn into_value(self) -> Option<ValueType<'a, T>> {
match self {
SPathValue::Value(value) => Some(ValueType::Value(value)),
SPathValue::Node(node) => Some(ValueType::Node(node)),
SPathValue::Nothing => Some(ValueType::Nothing),
_ => None,
}
}
}
#[derive(Debug, Default, PartialEq, Clone)]
pub struct NodesType<'a, T: VariantValue>(NodeList<'a, T>);
impl<'a, T: VariantValue> NodesType<'a, T> {
pub fn all(self) -> Vec<&'a T> {
self.0.all()
}
}
impl<'a, T: VariantValue> IntoIterator for NodesType<'a, T> {
type Item = &'a T;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a, T: VariantValue> Deref for NodesType<'a, T> {
type Target = NodeList<'a, T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: VariantValue> DerefMut for NodesType<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<'a, T: VariantValue> From<NodeList<'a, T>> for NodesType<'a, T> {
fn from(value: NodeList<'a, T>) -> Self {
Self(value)
}
}
impl<'a, T: VariantValue> From<Vec<&'a T>> for NodesType<'a, T> {
fn from(values: Vec<&'a T>) -> Self {
Self(NodeList::new(values))
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub enum LogicalType {
True,
#[default]
False,
}
impl From<LogicalType> for bool {
fn from(value: LogicalType) -> Self {
match value {
LogicalType::True => true,
LogicalType::False => false,
}
}
}
impl From<bool> for LogicalType {
fn from(value: bool) -> Self {
match value {
true => Self::True,
false => Self::False,
}
}
}
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub enum ValueType<'a, T: VariantValue> {
Value(T),
Node(&'a T),
#[default]
Nothing,
}
impl<T: VariantValue> ValueType<'_, T> {
pub fn as_value(&self) -> Option<&T> {
match self {
ValueType::Value(v) => Some(v),
ValueType::Node(v) => Some(*v),
ValueType::Nothing => None,
}
}
pub fn is_nothing(&self) -> bool {
matches!(self, ValueType::Nothing)
}
}
impl<T: VariantValue> From<T> for ValueType<'_, T> {
fn from(value: T) -> Self {
Self::Value(value)
}
}