use super::{
annotation::Annotation,
dependency_graph::{DependencyGraph, PosNeg},
sem_act::SemAct,
};
use crate::{Node, Pred, ShapeLabelIdx};
use itertools::Itertools;
use rbe::RbeTable;
use std::{collections::HashMap, fmt::Display};
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Shape {
closed: bool,
extra: Vec<Pred>,
rbe_table: RbeTable<Pred, Node, ShapeLabelIdx>,
sem_acts: Vec<SemAct>,
annotations: Vec<Annotation>,
preds: Vec<Pred>,
extends: Vec<ShapeLabelIdx>,
references: HashMap<Pred, Vec<ShapeLabelIdx>>,
display: String,
}
impl Shape {
#[allow(clippy::too_many_arguments)]
pub fn new(
closed: bool,
extra: Vec<Pred>,
rbe_table: RbeTable<Pred, Node, ShapeLabelIdx>,
sem_acts: Vec<SemAct>,
annotations: Vec<Annotation>,
preds: Vec<Pred>,
extends: Vec<ShapeLabelIdx>,
references: HashMap<Pred, Vec<ShapeLabelIdx>>,
display: String,
) -> Self {
Shape {
closed,
extra,
rbe_table,
sem_acts,
annotations,
preds,
extends,
references,
display,
}
}
pub fn preds(&self) -> Vec<Pred> {
self.preds.clone()
}
pub fn references(&self) -> &HashMap<Pred, Vec<ShapeLabelIdx>> {
&self.references
}
pub fn rbe_table(&self) -> &RbeTable<Pred, Node, ShapeLabelIdx> {
&self.rbe_table
}
pub fn is_closed(&self) -> bool {
self.closed
}
pub fn show_short(&self) -> String {
let closed = if self.closed { "CLOSED" } else { "" };
let extra = if self.extra.is_empty() {
"".to_string()
} else {
format!("EXTRA [{}]", self.extra.iter().join(" "))
};
format!("Shape {closed}{extra}")
}
pub fn add_edges(&self, source: ShapeLabelIdx, graph: &mut DependencyGraph, pos_neg: PosNeg) {
for (_component, _pred, cond) in self.rbe_table.components() {
match cond {
rbe::MatchCond::Single(_single_cond) => {}
rbe::MatchCond::And(_match_conds) => {}
rbe::MatchCond::Ref(r) => graph.add_edge(source, r, pos_neg),
}
}
}
}
impl Display for Shape {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let extends = if self.extends.is_empty() {
"".to_string()
} else {
format!(
"EXTENDS [{}]",
self.extends.iter().map(|e| e.to_string()).join(" ")
)
};
let closed = if self.closed { "CLOSED" } else { "" };
let extra = if self.extra.is_empty() {
"".to_string()
} else {
format!("EXTRA [{}]", self.extra.iter().join(" "))
};
let preds = if self.preds.is_empty() {
"".to_string()
} else {
self.preds.iter().join(",")
};
write!(f, "Shape {extends}{closed}{extra} ")?;
writeln!(f, "Preds: {preds}")?;
writeln!(f, "{}", self.rbe_table)?;
Ok(())
}
}