shex_ast/ir/
shape.rs

1use super::{
2    annotation::Annotation,
3    dependency_graph::{DependencyGraph, PosNeg},
4    sem_act::SemAct,
5};
6use crate::{Node, Pred, ShapeLabelIdx};
7use itertools::Itertools;
8use rbe::RbeTable;
9use std::{collections::HashMap, fmt::Display};
10
11#[derive(Debug, PartialEq, Eq, Clone)]
12pub struct Shape {
13    closed: bool,
14    extra: Vec<Pred>,
15    rbe_table: RbeTable<Pred, Node, ShapeLabelIdx>,
16    sem_acts: Vec<SemAct>,
17    annotations: Vec<Annotation>,
18    preds: Vec<Pred>,
19    references: HashMap<Pred, Vec<ShapeLabelIdx>>,
20    display: String,
21}
22
23impl Shape {
24    #[allow(clippy::too_many_arguments)]
25    pub fn new(
26        closed: bool,
27        extra: Vec<Pred>,
28        rbe_table: RbeTable<Pred, Node, ShapeLabelIdx>,
29        sem_acts: Vec<SemAct>,
30        annotations: Vec<Annotation>,
31        preds: Vec<Pred>,
32        references: HashMap<Pred, Vec<ShapeLabelIdx>>,
33        display: String,
34    ) -> Self {
35        Shape {
36            closed,
37            extra,
38            rbe_table,
39            sem_acts,
40            annotations,
41            preds,
42            references,
43            display,
44        }
45    }
46
47    pub fn preds(&self) -> Vec<Pred> {
48        self.preds.clone()
49    }
50
51    pub fn references(&self) -> &HashMap<Pred, Vec<ShapeLabelIdx>> {
52        &self.references
53    }
54
55    pub fn rbe_table(&self) -> &RbeTable<Pred, Node, ShapeLabelIdx> {
56        &self.rbe_table
57    }
58
59    pub fn is_closed(&self) -> bool {
60        self.closed
61    }
62
63    pub fn show_short(&self) -> String {
64        let closed = if self.closed { "CLOSED" } else { "" };
65        let extra = if self.extra.is_empty() {
66            "".to_string()
67        } else {
68            format!("EXTRA [{}]", self.extra.iter().join(" "))
69        };
70        format!("Shape {closed}{extra}")
71    }
72
73    pub fn add_edges(&self, source: ShapeLabelIdx, graph: &mut DependencyGraph, pos_neg: PosNeg) {
74        for (_component, _pred, cond) in self.rbe_table.components() {
75            match cond {
76                rbe::MatchCond::Single(_single_cond) => {}
77                rbe::MatchCond::And(_match_conds) => {}
78                rbe::MatchCond::Ref(r) => graph.add_edge(source, r, pos_neg),
79            }
80        }
81    }
82}
83
84impl Display for Shape {
85    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86        let closed = if self.closed { "CLOSED" } else { "" };
87        let extra = if self.extra.is_empty() {
88            "".to_string()
89        } else {
90            format!("EXTRA [{}]", self.extra.iter().join(" "))
91        };
92        let preds = if self.preds.is_empty() {
93            "".to_string()
94        } else {
95            self.preds.iter().join(",")
96        };
97        write!(f, "Shape {closed}{extra} ")?;
98        writeln!(f, "Preds: {}", preds)?;
99        writeln!(f, "{}", self.rbe_table)?;
100        Ok(())
101    }
102}