use crate::shape::Shape;
use prefixmap::IriRef;
use rudof_rdf::rdf_core::term::literal::ConcreteLiteral;
use rudof_rdf::rdf_core::term::{IriOrBlankNode, Object};
use rudof_rdf::rdf_core::{Rdf, SHACLPath};
use std::collections::HashMap;
use std::fmt::{Display, Formatter};
#[allow(dead_code)]
#[derive(Debug)]
pub enum NodeExpr<RDF: Rdf> {
Iri(IriRef),
Literal(ConcreteLiteral),
NamedParameterFn(HashMap<IriRef, NodeExpr<RDF>>),
ListParameterFn {
property: IriRef,
args: Vec<NodeExpr<RDF>>,
},
Empty,
Var(String),
List(Vec<Object>),
PathValues {
path: SHACLPath,
focus_node: Option<Box<NodeExpr<RDF>>>,
},
Exists(Box<NodeExpr<RDF>>),
IfExpression {
if_condition: Box<NodeExpr<RDF>>,
then: Box<NodeExpr<RDF>>,
else_expression: Box<NodeExpr<RDF>>,
},
Distinct(Box<NodeExpr<RDF>>),
Intersection(Vec<NodeExpr<RDF>>),
Concat(Vec<NodeExpr<RDF>>),
Remove {
remove: Box<NodeExpr<RDF>>,
nodes: Box<NodeExpr<RDF>>,
},
Filter {
filter_shape: Shape<RDF>,
nodes: Box<NodeExpr<RDF>>,
},
Limit {
limit: usize,
nodes: Box<NodeExpr<RDF>>,
},
Offset {
offset: usize,
nodes: Box<NodeExpr<RDF>>,
},
FlatMap {
flat_map: Box<NodeExpr<RDF>>,
nodes: Box<NodeExpr<RDF>>,
},
FindFirst {
find_first: Shape<RDF>,
nodes: Box<NodeExpr<RDF>>,
},
MatchAll {
match_all: Shape<RDF>,
nodes: Box<NodeExpr<RDF>>,
},
Count(Box<NodeExpr<RDF>>),
Min(Box<NodeExpr<RDF>>),
Max(Box<NodeExpr<RDF>>),
Sum(Box<NodeExpr<RDF>>),
InstancesOf(IriRef),
NodesMatching(IriOrBlankNode),
}
impl<RDF: Rdf> Display for NodeExpr<RDF> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
NodeExpr::Iri(i) => write!(f, "iri({i})"),
NodeExpr::Literal(l) => write!(f, "literal({l})"),
NodeExpr::NamedParameterFn(map) => {
let params = map
.iter()
.map(|(k, v)| format!("{}: {}", k, v))
.collect::<Vec<_>>()
.join(", ");
write!(f, "namedParameterFn({params})")
},
NodeExpr::ListParameterFn { args, property } => {
let args_str = args.iter().map(|arg| arg.to_string()).collect::<Vec<_>>().join(", ");
write!(f, "listParameterFn({property}, {args_str})")
},
NodeExpr::Empty => write!(f, "empty"),
NodeExpr::Var(v) => write!(f, "var({v})"),
NodeExpr::List(l) => write!(
f,
"list({})",
l.iter().map(|o| o.to_string()).collect::<Vec<_>>().join(", ")
),
NodeExpr::PathValues { focus_node, path } => {
let fnode = match focus_node {
None => "".to_string(),
Some(n) => n.to_string(),
};
write!(f, "pathValues({path}, {fnode})")
},
NodeExpr::Exists(e) => write!(f, "exists({e})"),
NodeExpr::IfExpression {
if_condition,
then,
else_expression,
} => {
write!(f, "if({if_condition} then {then} else {else_expression})")
},
NodeExpr::Distinct(d) => write!(f, "distinct({d})"),
NodeExpr::Intersection(i) => write!(
f,
"intersection({})",
i.iter().map(|e| e.to_string()).collect::<Vec<_>>().join(", ")
),
NodeExpr::Concat(c) => write!(
f,
"concat({})",
c.iter().map(|e| e.to_string()).collect::<Vec<_>>().join(", ")
),
NodeExpr::Remove { remove, nodes } => write!(f, "remove({remove} in {nodes})"),
NodeExpr::Filter { filter_shape, nodes } => write!(f, "filter({filter_shape} in {nodes})"),
NodeExpr::Limit { limit, nodes } => writeln!(f, "limit({limit} in {nodes})"),
NodeExpr::Offset { offset, nodes } => writeln!(f, "offset({offset} in {nodes})"),
NodeExpr::FlatMap { flat_map, nodes } => write!(f, "flatMap({flat_map} in {nodes}"),
NodeExpr::FindFirst { find_first, nodes } => write!(f, "findFirst({find_first} in {nodes}"),
NodeExpr::MatchAll { match_all, nodes } => write!(f, "matchAll({match_all} in {nodes}"),
NodeExpr::Count(c) => write!(f, "count({c})"),
NodeExpr::Min(m) => write!(f, "min({m})"),
NodeExpr::Max(m) => write!(f, "max({m}"),
NodeExpr::Sum(s) => write!(f, "sum({s})"),
NodeExpr::InstancesOf(i) => write!(f, "instancesOf({i})"),
NodeExpr::NodesMatching(n) => write!(f, "nodesMatching({n})"),
}
}
}
impl<RDF: Rdf> Clone for NodeExpr<RDF> {
fn clone(&self) -> Self {
match self {
NodeExpr::Iri(i) => NodeExpr::Iri(i.clone()),
NodeExpr::Literal(l) => NodeExpr::Literal(l.clone()),
NodeExpr::NamedParameterFn(map) => NodeExpr::NamedParameterFn(map.clone()),
NodeExpr::ListParameterFn { property, args } => NodeExpr::ListParameterFn {
property: property.clone(),
args: args.clone(),
},
NodeExpr::Empty => NodeExpr::Empty,
NodeExpr::Var(v) => NodeExpr::Var(v.clone()),
NodeExpr::List(l) => NodeExpr::List(l.clone()),
NodeExpr::PathValues { path, focus_node } => NodeExpr::PathValues {
path: path.clone(),
focus_node: focus_node.clone(),
},
NodeExpr::Exists(e) => NodeExpr::Exists(e.clone()),
NodeExpr::IfExpression {
if_condition,
then,
else_expression,
} => NodeExpr::IfExpression {
if_condition: if_condition.clone(),
then: then.clone(),
else_expression: else_expression.clone(),
},
NodeExpr::Distinct(d) => NodeExpr::Distinct(d.clone()),
NodeExpr::Intersection(i) => NodeExpr::Intersection(i.clone()),
NodeExpr::Concat(c) => NodeExpr::Concat(c.clone()),
NodeExpr::Remove { remove, nodes } => NodeExpr::Remove {
remove: remove.clone(),
nodes: nodes.clone(),
},
NodeExpr::Filter { filter_shape, nodes } => NodeExpr::Filter {
filter_shape: filter_shape.clone(),
nodes: nodes.clone(),
},
NodeExpr::Limit { limit, nodes } => NodeExpr::Limit {
limit: *limit,
nodes: nodes.clone(),
},
NodeExpr::Offset { offset, nodes } => NodeExpr::Offset {
offset: *offset,
nodes: nodes.clone(),
},
NodeExpr::FlatMap { flat_map, nodes } => NodeExpr::FlatMap {
flat_map: flat_map.clone(),
nodes: nodes.clone(),
},
NodeExpr::FindFirst { find_first, nodes } => NodeExpr::FindFirst {
find_first: find_first.clone(),
nodes: nodes.clone(),
},
NodeExpr::MatchAll { match_all, nodes } => NodeExpr::MatchAll {
match_all: match_all.clone(),
nodes: nodes.clone(),
},
NodeExpr::Count(c) => NodeExpr::Count(c.clone()),
NodeExpr::Min(m) => NodeExpr::Min(m.clone()),
NodeExpr::Max(m) => NodeExpr::Max(m.clone()),
NodeExpr::Sum(s) => NodeExpr::Sum(s.clone()),
NodeExpr::InstancesOf(i) => NodeExpr::InstancesOf(i.clone()),
NodeExpr::NodesMatching(n) => NodeExpr::NodesMatching(n.clone()),
}
}
}
impl<RDF: Rdf> PartialEq for NodeExpr<RDF> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(NodeExpr::Iri(l), NodeExpr::Iri(r)) => l == r,
(NodeExpr::Literal(l), NodeExpr::Literal(r)) => l == r,
(NodeExpr::NamedParameterFn(l), NodeExpr::NamedParameterFn(r)) => l == r,
(
NodeExpr::ListParameterFn { args: al, property: pl },
NodeExpr::ListParameterFn { args: ar, property: pr },
) => al == ar && pl == pr,
(NodeExpr::Empty, NodeExpr::Empty) => true,
(NodeExpr::Var(l), NodeExpr::Var(r)) => l == r,
(NodeExpr::List(l), NodeExpr::List(r)) => l == r,
(
NodeExpr::PathValues {
focus_node: fl,
path: pl,
},
NodeExpr::PathValues {
focus_node: fr,
path: pr,
},
) => pl == pr && fl == fr,
(NodeExpr::Exists(l), NodeExpr::Exists(r)) => l == r,
(
NodeExpr::IfExpression {
if_condition: il,
then: tl,
else_expression: el,
},
NodeExpr::IfExpression {
if_condition: ir,
then: tr,
else_expression: er,
},
) => il == ir && tl == tr && el == er,
(NodeExpr::Distinct(l), NodeExpr::Distinct(r)) => l == r,
(NodeExpr::Intersection(l), NodeExpr::Intersection(r)) => l == r,
(NodeExpr::Concat(l), NodeExpr::Concat(r)) => l == r,
(NodeExpr::Remove { remove: rl, nodes: nl }, NodeExpr::Remove { remove: rr, nodes: nr }) => {
rl == rr && nl == nr
},
(
NodeExpr::Filter {
filter_shape: fl,
nodes: nl,
},
NodeExpr::Filter {
filter_shape: fr,
nodes: nr,
},
) => fl == fr && nl == nr,
(NodeExpr::Limit { limit: ll, nodes: nl }, NodeExpr::Limit { limit: lr, nodes: nr }) => {
ll == lr && nl == nr
},
(NodeExpr::Offset { offset: ol, nodes: nl }, NodeExpr::Offset { offset: or, nodes: nr }) => {
ol == or && nl == nr
},
(
NodeExpr::FlatMap {
flat_map: fl,
nodes: nl,
},
NodeExpr::FlatMap {
flat_map: fr,
nodes: nr,
},
) => fl == fr && nl == nr,
(
NodeExpr::FindFirst {
find_first: fl,
nodes: nl,
},
NodeExpr::FindFirst {
find_first: fr,
nodes: nr,
},
) => fl == fr && nl == nr,
(
NodeExpr::MatchAll {
match_all: ml,
nodes: nl,
},
NodeExpr::MatchAll {
match_all: mr,
nodes: nr,
},
) => ml == mr && nl == nr,
(NodeExpr::Count(l), NodeExpr::Count(r)) => l == r,
(NodeExpr::Min(l), NodeExpr::Min(r)) => l == r,
(NodeExpr::Max(l), NodeExpr::Max(r)) => l == r,
(NodeExpr::Sum(l), NodeExpr::Sum(r)) => l == r,
(NodeExpr::InstancesOf(l), NodeExpr::InstancesOf(r)) => l == r,
(NodeExpr::NodesMatching(l), NodeExpr::NodesMatching(r)) => l == r,
_ => false,
}
}
}