use crate::ast::{ASTSchema, ASTShape};
use crate::ir::ReifierInfo;
use crate::ir::component::IRComponent;
use crate::ir::dg::{DependencyGraph, PosNeg};
use crate::ir::error::IRError;
use crate::ir::node_shape::IRNodeShape;
use crate::ir::property_shape::IRPropertyShape;
use crate::ir::schema::IRSchema;
use crate::ir::shape_label_idx::ShapeLabelIdx;
use crate::types::{MessageMap, Severity, Target};
use rudof_iri::IriS;
use rudof_rdf::rdf_core::term::Object;
use rudof_rdf::rdf_core::{BuildRDF, SHACLPath};
use std::collections::{HashMap, HashSet};
use std::fmt::{Display, Formatter};
#[derive(Debug, Clone)]
pub enum IRShape {
NodeShape(Box<IRNodeShape>),
PropertyShape(Box<IRPropertyShape>),
}
impl IRShape {
pub fn node_shape(ns: IRNodeShape) -> Self {
Self::NodeShape(Box::new(ns))
}
pub fn property_shape(ps: IRPropertyShape) -> Self {
Self::PropertyShape(Box::new(ps))
}
pub fn deactivated(&self) -> bool {
match self {
IRShape::NodeShape(ns) => ns.deactivated(),
IRShape::PropertyShape(ps) => ps.deactivated(),
}
}
pub fn reifier_info(&self) -> Option<&ReifierInfo> {
match self {
IRShape::NodeShape(_) => None,
IRShape::PropertyShape(ps) => ps.reifier_info(),
}
}
pub fn path(&self) -> Option<&SHACLPath> {
match self {
IRShape::NodeShape(_) => None,
IRShape::PropertyShape(ps) => Some(ps.path()),
}
}
pub fn severity(&self) -> &Severity {
match self {
IRShape::NodeShape(ns) => ns.severity(),
IRShape::PropertyShape(ps) => ps.severity(),
}
}
pub fn id(&self) -> &Object {
match self {
IRShape::NodeShape(ns) => ns.id(),
IRShape::PropertyShape(ps) => ps.id(),
}
}
pub fn targets(&self) -> &Vec<Target> {
match self {
IRShape::NodeShape(ns) => ns.targets(),
IRShape::PropertyShape(ps) => ps.targets(),
}
}
pub fn components(&self) -> &Vec<IRComponent> {
match self {
IRShape::NodeShape(ns) => ns.components(),
IRShape::PropertyShape(ps) => ps.components(),
}
}
pub fn property_shapes(&self) -> &Vec<ShapeLabelIdx> {
match self {
IRShape::NodeShape(ns) => ns.property_shapes(),
IRShape::PropertyShape(ps) => ps.property_shapes(),
}
}
pub fn closed(&self) -> bool {
match self {
IRShape::NodeShape(ns) => ns.closed(),
IRShape::PropertyShape(ps) => ps.closed(),
}
}
pub fn allowed_properties(&self) -> HashSet<IriS> {
match self {
IRShape::NodeShape(ns) => ns.allowed_properties(),
IRShape::PropertyShape(ps) => ps.allowed_properties(),
}
}
pub fn message(&self) -> Option<&MessageMap> {
match self {
IRShape::NodeShape(ns) => ns.message(),
IRShape::PropertyShape(ps) => ps.message(),
}
}
pub fn name(&self) -> Option<&MessageMap> {
match self {
IRShape::NodeShape(ns) => ns.name(),
IRShape::PropertyShape(ps) => ps.name(),
}
}
pub fn description(&self) -> Option<&MessageMap> {
match self {
IRShape::NodeShape(ns) => ns.description(),
IRShape::PropertyShape(ps) => ps.description(),
}
}
}
impl IRShape {
pub fn compile(shape: &ASTShape, ast: &ASTSchema, ir: &mut IRSchema) -> Result<Self, IRError> {
let shape = match shape {
ASTShape::NodeShape(shape) => {
let shape = IRNodeShape::compile(shape, ast, ir)?;
IRShape::node_shape(shape)
},
ASTShape::PropertyShape(shape) => {
let shape = IRPropertyShape::compile(shape, ast, ir)?;
IRShape::property_shape(shape)
},
};
Ok(shape)
}
}
impl Display for IRShape {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
IRShape::NodeShape(ns) => write!(f, "{ns}")?,
IRShape::PropertyShape(ps) => write!(f, "{ps}")?,
}
Ok(())
}
}
impl IRShape {
pub fn register<RDF: BuildRDF>(
&self,
graph: &mut RDF,
shapes_map: &HashMap<ShapeLabelIdx, IRShape>,
) -> Result<(), IRError> {
match self {
IRShape::NodeShape(ns) => ns.register(graph, shapes_map),
IRShape::PropertyShape(ps) => ps.register(graph, shapes_map),
}
}
}
impl IRShape {
pub fn add_edges(
&self,
idx: ShapeLabelIdx,
dg: &mut DependencyGraph,
posneg: PosNeg,
ir: &IRSchema,
cache: &mut HashSet<ShapeLabelIdx>,
) {
match self {
IRShape::NodeShape(ns) => ns.add_edges(idx, dg, posneg, ir, cache),
IRShape::PropertyShape(ps) => ps.add_edges(idx, dg, posneg, ir, cache),
}
}
}