1use std::fmt::{Display, Formatter};
21
22#[derive(Debug, PartialEq, Clone, Eq, Hash)]
25pub struct Port(pub Option<Id>, pub Option<String>);
26
27#[derive(Debug, Clone, PartialEq, Eq, Hash)]
31pub enum Id {
32 Html(String),
33 Escaped(String),
34 Plain(String),
35 Anonymous(String),
36}
37
38impl Display for Id {
39 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40 match self {
41 Id::Html(v) => f.write_str(format!("html {}", v).as_str()),
42 Id::Escaped(v) => f.write_str(format!("esc {}", v).as_str()),
43 Id::Plain(v) => f.write_str(format!("{}", v).as_str()),
44 Id::Anonymous(v) => f.write_str(format!("anon {}", v).as_str()),
45 }
46 }
47}
48
49#[derive(Debug, PartialEq, Eq, Clone, Hash)]
52pub struct NodeId(pub Id, pub Option<Port>);
53
54#[derive(PartialEq, Debug, Clone)]
56pub struct Attribute(pub Id, pub Id);
57
58#[derive(PartialEq, Debug, Clone)]
60pub enum GraphAttributes {
61 Graph(Vec<Attribute>),
62 Node(Vec<Attribute>),
63 Edge(Vec<Attribute>),
64}
65
66impl GraphAttributes {
67 pub fn new(ty: &str, attrs: Vec<Attribute>) -> Self {
68 match ty.to_lowercase().as_str() {
69 "graph" => GraphAttributes::Graph(attrs),
70 "node" => GraphAttributes::Node(attrs),
71 "edge" => GraphAttributes::Edge(attrs),
72 _ => panic!("only graph, node, edge is applied here. "),
73 }
74 }
75}
76
77#[derive(Debug, PartialEq, Clone)]
79pub struct Edge {
80 pub ty: EdgeTy,
81 pub attributes: Vec<Attribute>,
82}
83
84impl Edge {
85 fn add_attr(&mut self, attr: Attribute) {
86 self.attributes.push(attr)
87 }
88}
89
90#[derive(Debug, PartialEq, Clone)]
93pub enum EdgeTy {
94 Pair(Vertex, Vertex),
95 Chain(Vec<Vertex>),
96}
97
98#[derive(Debug, PartialEq, Clone)]
100pub struct Node {
101 pub id: NodeId,
102 pub attributes: Vec<Attribute>,
103}
104
105impl Node {
106 pub fn new(id: NodeId, attributes: Vec<Attribute>) -> Self {
107 Node { id, attributes }
108 }
109}
110
111#[derive(PartialEq, Debug, Clone)]
113pub enum Stmt {
114 Node(Node),
115 Subgraph(Subgraph),
116 Attribute(Attribute),
117 GAttribute(GraphAttributes),
118 Edge(Edge),
119}
120
121impl From<Node> for Stmt {
122 fn from(v: Node) -> Self {
123 Stmt::Node(v)
124 }
125}
126
127impl From<Edge> for Stmt {
128 fn from(v: Edge) -> Self {
129 Stmt::Edge(v)
130 }
131}
132
133impl From<GraphAttributes> for Stmt {
134 fn from(v: GraphAttributes) -> Self {
135 Stmt::GAttribute(v)
136 }
137}
138
139impl From<Attribute> for Stmt {
140 fn from(v: Attribute) -> Self {
141 Stmt::Attribute(v)
142 }
143}
144
145impl From<Subgraph> for Stmt {
146 fn from(v: Subgraph) -> Self {
147 Stmt::Subgraph(v)
148 }
149}
150
151#[derive(PartialEq, Debug, Clone)]
153pub struct Subgraph {
154 pub id: Id,
155 pub stmts: Vec<Stmt>,
156}
157
158impl Subgraph {
159 pub fn add_stmt(&mut self, stmt: Stmt) {
160 self.stmts.push(stmt)
161 }
162}
163
164#[derive(PartialEq, Debug, Clone)]
166pub enum Vertex {
167 N(NodeId),
168 S(Subgraph),
169}
170
171impl From<NodeId> for Vertex {
172 fn from(v: NodeId) -> Self {
173 Vertex::N(v)
174 }
175}
176
177impl From<Subgraph> for Vertex {
178 fn from(v: Subgraph) -> Self {
179 Vertex::S(v)
180 }
181}
182
183#[derive(Debug, PartialEq, Clone)]
185pub enum Graph {
186 Graph {
187 id: Id,
188 strict: bool,
189 stmts: Vec<Stmt>,
190 },
191 DiGraph {
192 id: Id,
193 strict: bool,
194 stmts: Vec<Stmt>,
195 },
196}
197
198impl Graph {
199 pub fn add_stmt(&mut self, stmt: Stmt) {
200 match self {
201 Graph::Graph { stmts, .. } => stmts.push(stmt),
202 Graph::DiGraph { stmts, .. } => stmts.push(stmt),
203 }
204 }
205}