use seesaw_tgg::rules::format::{CorrDecl, NodeDecl, Role, RuleDecl, SideDecl};
#[must_use]
pub fn one_to_one(name: &str, left: &str, right: &str, corr: &str) -> RuleDecl {
RuleDecl {
name: name.to_string(),
rank: 0,
documentation: None,
left: side("l", left),
right: side("r", right),
corrs: vec![CorrDecl {
typ: corr.to_string(),
left: "l".to_string(),
right: "r".to_string(),
role: Role::Establishes,
bindings: Vec::new(),
}],
joins: Vec::new(),
}
}
#[must_use]
pub fn part_of(name: &str, left: (&str, &str, &str), right: (&str, &str, &str)) -> RuleDecl {
let (l_part, l_owner, owner_corr) = left;
let (r_part, r_owner, part_corr) = right;
RuleDecl {
name: name.to_string(),
rank: 1,
documentation: None,
left: SideDecl {
anchor: "part".to_string(),
nodes: vec![node("part", l_part), context_node("owner", l_owner)],
links: vec![("owner".to_string(), "part".to_string())],
same_value_links: Vec::new(),
},
right: SideDecl {
anchor: "part".to_string(),
nodes: vec![node("part", r_part), node("owner", r_owner)],
links: vec![("owner".to_string(), "part".to_string())],
same_value_links: Vec::new(),
},
corrs: vec![
CorrDecl {
typ: part_corr.to_string(),
left: "part".to_string(),
right: "part".to_string(),
role: Role::Establishes,
bindings: Vec::new(),
},
CorrDecl {
typ: owner_corr.to_string(),
left: "owner".to_string(),
right: "owner".to_string(),
role: Role::References,
bindings: Vec::new(),
},
],
joins: Vec::new(),
}
}
fn side(anchor: &str, typ: &str) -> SideDecl {
SideDecl {
anchor: anchor.to_string(),
nodes: vec![node(anchor, typ)],
links: Vec::new(),
same_value_links: Vec::new(),
}
}
fn node(name: &str, typ: &str) -> NodeDecl {
NodeDecl {
name: name.to_string(),
typ: typ.to_string(),
predicate: None,
context: false,
same_as: None,
constant: None,
}
}
fn context_node(name: &str, typ: &str) -> NodeDecl {
NodeDecl {
name: name.to_string(),
typ: typ.to_string(),
predicate: None,
context: true,
same_as: None,
constant: None,
}
}