1use std::{borrow::Cow, rc::Rc, sync::Arc};
4
5use super::HugrView;
6use crate::hugr::internal::{HugrInternals, HugrMutInternals};
7use crate::hugr::{HugrMut, hugrmut::InsertForestResult};
8
9macro_rules! hugr_internal_methods {
10 ($arg:ident, $e:expr) => {
12 delegate::delegate! {
13 to ({let $arg=self; $e}) {
14 fn region_portgraph(&self, parent: Self::Node) -> (portgraph::view::FlatRegion<'_, Self::RegionPortgraph<'_>>, Self::RegionPortgraphNodes);
15 fn node_metadata_map(&self, node: Self::Node) -> &crate::hugr::NodeMetadataMap;
16 }
17 }
18 };
19}
20pub(crate) use hugr_internal_methods;
21
22macro_rules! hugr_view_methods {
23 ($arg:ident, $e:expr) => {
25 delegate::delegate! {
26 to ({let $arg=self; $e}) {
27 fn entrypoint(&self) -> Self::Node;
28 fn entrypoint_optype(&self) -> &crate::ops::OpType;
29 fn module_root(&self) -> Self::Node;
30 fn contains_node(&self, node: Self::Node) -> bool;
31 fn get_parent(&self, node: Self::Node) -> Option<Self::Node>;
32 fn get_metadata(&self, node: Self::Node, key: impl AsRef<str>) -> Option<&crate::hugr::NodeMetadata>;
33 fn get_optype(&self, node: Self::Node) -> &crate::ops::OpType;
34 fn num_nodes(&self) -> usize;
35 fn num_edges(&self) -> usize;
36 fn num_ports(&self, node: Self::Node, dir: crate::Direction) -> usize;
37 fn num_inputs(&self, node: Self::Node) -> usize;
38 fn num_outputs(&self, node: Self::Node) -> usize;
39 fn nodes(&self) -> impl Iterator<Item = Self::Node> + Clone;
40 fn node_ports(&self, node: Self::Node, dir: crate::Direction) -> impl Iterator<Item = crate::Port> + Clone;
41 fn node_outputs(&self, node: Self::Node) -> impl Iterator<Item = crate::OutgoingPort> + Clone;
42 fn node_inputs(&self, node: Self::Node) -> impl Iterator<Item = crate::IncomingPort> + Clone;
43 fn all_node_ports(&self, node: Self::Node) -> impl Iterator<Item = crate::Port> + Clone;
44 fn linked_ports(&self, node: Self::Node, port: impl Into<crate::Port>) -> impl Iterator<Item = (Self::Node, crate::Port)> + Clone;
45 fn all_linked_ports(&self, node: Self::Node, dir: crate::Direction) -> itertools::Either<impl Iterator<Item = (Self::Node, crate::OutgoingPort)>, impl Iterator<Item = (Self::Node, crate::IncomingPort)>>;
46 fn all_linked_outputs(&self, node: Self::Node) -> impl Iterator<Item = (Self::Node, crate::OutgoingPort)>;
47 fn all_linked_inputs(&self, node: Self::Node) -> impl Iterator<Item = (Self::Node, crate::IncomingPort)>;
48 fn single_linked_port(&self, node: Self::Node, port: impl Into<crate::Port>) -> Option<(Self::Node, crate::Port)>;
49 fn single_linked_output(&self, node: Self::Node, port: impl Into<crate::IncomingPort>) -> Option<(Self::Node, crate::OutgoingPort)>;
50 fn single_linked_input(&self, node: Self::Node, port: impl Into<crate::OutgoingPort>) -> Option<(Self::Node, crate::IncomingPort)>;
51 fn linked_outputs(&self, node: Self::Node, port: impl Into<crate::IncomingPort>) -> impl Iterator<Item = (Self::Node, crate::OutgoingPort)>;
52 fn linked_inputs(&self, node: Self::Node, port: impl Into<crate::OutgoingPort>) -> impl Iterator<Item = (Self::Node, crate::IncomingPort)>;
53 fn node_connections(&self, node: Self::Node, other: Self::Node) -> impl Iterator<Item = [crate::Port; 2]> + Clone;
54 fn is_linked(&self, node: Self::Node, port: impl Into<crate::Port>) -> bool;
55 fn children(&self, node: Self::Node) -> impl DoubleEndedIterator<Item = Self::Node> + Clone;
56 fn descendants(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> + Clone;
57 fn first_child(&self, node: Self::Node) -> Option<Self::Node>;
58 fn neighbours(&self, node: Self::Node, dir: crate::Direction) -> impl Iterator<Item = Self::Node> + Clone;
59 fn all_neighbours(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> + Clone;
60 fn mermaid_string(&self) -> String;
61 #[allow(deprecated)]
62 fn mermaid_string_with_config(&self, config: crate::hugr::views::render::RenderConfig<Self::Node>) -> String;
63 fn mermaid_string_with_formatter(&self, #[into] formatter: crate::hugr::views::render::MermaidFormatter<Self>) -> String;
64 fn dot_string(&self) -> String;
65 fn static_source(&self, node: Self::Node) -> Option<Self::Node>;
66 fn static_targets(&self, node: Self::Node) -> Option<impl Iterator<Item = (Self::Node, crate::IncomingPort)>>;
67 fn value_types(&self, node: Self::Node, dir: crate::Direction) -> impl Iterator<Item = (crate::Port, crate::types::Type)>;
68 fn extensions(&self) -> &crate::extension::ExtensionRegistry;
69 fn validate(&self) -> Result<(), crate::hugr::ValidationError<Self::Node>>;
70 fn extract_hugr(&self, parent: Self::Node) -> (crate::Hugr, impl crate::hugr::views::ExtractionResult<Self::Node> + 'static);
71 }
72 }
73 }
74}
75pub(crate) use hugr_view_methods;
76
77macro_rules! hugr_mut_internal_methods {
78 ($arg:ident, $e:expr) => {
80 delegate::delegate! {
81 to ({let $arg=self; $e}) {
82 fn set_module_root(&mut self, root: Self::Node);
83 fn set_num_ports(&mut self, node: Self::Node, incoming: usize, outgoing: usize);
84 fn add_ports(&mut self, node: Self::Node, direction: crate::Direction, amount: isize) -> std::ops::Range<usize>;
85 fn insert_ports(&mut self, node: Self::Node, direction: crate::Direction, index: usize, amount: usize) -> std::ops::Range<usize>;
86 fn set_parent(&mut self, node: Self::Node, parent: Self::Node);
87 fn move_after_sibling(&mut self, node: Self::Node, after: Self::Node);
88 fn move_before_sibling(&mut self, node: Self::Node, before: Self::Node);
89 fn replace_op(&mut self, node: Self::Node, op: impl Into<crate::ops::OpType>) -> crate::ops::OpType;
90 fn optype_mut(&mut self, node: Self::Node) -> &mut crate::ops::OpType;
91 fn node_metadata_map_mut(&mut self, node: Self::Node) -> &mut crate::hugr::NodeMetadataMap;
92 fn extensions_mut(&mut self) -> &mut crate::extension::ExtensionRegistry;
93 }
94 }
95 };
96}
97pub(crate) use hugr_mut_internal_methods;
98
99macro_rules! hugr_mut_methods {
100 ($arg:ident, $e:expr) => {
102 delegate::delegate! {
103 to ({let $arg=self; $e}) {
104 fn set_entrypoint(&mut self, root: Self::Node);
105 fn get_metadata_mut(&mut self, node: Self::Node, key: impl AsRef<str>) -> &mut crate::hugr::NodeMetadata;
106 fn set_metadata(&mut self, node: Self::Node, key: impl AsRef<str>, metadata: impl Into<crate::hugr::NodeMetadata>);
107 fn remove_metadata(&mut self, node: Self::Node, key: impl AsRef<str>);
108 fn add_node_with_parent(&mut self, parent: Self::Node, op: impl Into<crate::ops::OpType>) -> Self::Node;
109 fn add_node_before(&mut self, sibling: Self::Node, nodetype: impl Into<crate::ops::OpType>) -> Self::Node;
110 fn add_node_after(&mut self, sibling: Self::Node, op: impl Into<crate::ops::OpType>) -> Self::Node;
111 fn remove_node(&mut self, node: Self::Node) -> crate::ops::OpType;
112 fn remove_subtree(&mut self, node: Self::Node);
113 fn copy_descendants(&mut self, root: Self::Node, new_parent: Self::Node, subst: Option<crate::types::Substitution>) -> std::collections::BTreeMap<Self::Node, Self::Node>;
114 fn connect(&mut self, src: Self::Node, src_port: impl Into<crate::OutgoingPort>, dst: Self::Node, dst_port: impl Into<crate::IncomingPort>);
115 fn disconnect(&mut self, node: Self::Node, port: impl Into<crate::Port>);
116 fn add_other_edge(&mut self, src: Self::Node, dst: Self::Node) -> (crate::OutgoingPort, crate::IncomingPort);
117 fn insert_forest(&mut self, other: crate::Hugr, roots: impl IntoIterator<Item=(crate::Node, Self::Node)>) -> InsertForestResult<crate::Node, Self::Node>;
118 fn insert_view_forest<Other: crate::hugr::HugrView>(&mut self, other: &Other, nodes: impl Iterator<Item=Other::Node> + Clone, roots: impl IntoIterator<Item=(Other::Node, Self::Node)>) -> InsertForestResult<Other::Node, Self::Node>;
119 fn use_extension(&mut self, extension: impl Into<std::sync::Arc<crate::extension::Extension>>);
120 fn use_extensions<Reg>(&mut self, registry: impl IntoIterator<Item = Reg>) where crate::extension::ExtensionRegistry: Extend<Reg>;
121 }
122 }
123 };
124}
125pub(crate) use hugr_mut_methods;
126
127impl<T: HugrView> HugrInternals for &T {
129 type RegionPortgraph<'p>
130 = T::RegionPortgraph<'p>
131 where
132 Self: 'p;
133
134 type Node = T::Node;
135
136 type RegionPortgraphNodes = T::RegionPortgraphNodes;
137
138 hugr_internal_methods! {this, *this}
139}
140impl<T: HugrView> HugrView for &T {
141 hugr_view_methods! {this, *this}
142}
143
144impl<T: HugrView> HugrInternals for &mut T {
146 type RegionPortgraph<'p>
147 = T::RegionPortgraph<'p>
148 where
149 Self: 'p;
150
151 type Node = T::Node;
152
153 type RegionPortgraphNodes = T::RegionPortgraphNodes;
154
155 hugr_internal_methods! {this, &**this}
156}
157impl<T: HugrView> HugrView for &mut T {
158 hugr_view_methods! {this, &**this}
159}
160impl<T: HugrMutInternals> HugrMutInternals for &mut T {
161 hugr_mut_internal_methods! {this, &mut **this}
162}
163impl<T: HugrMut> HugrMut for &mut T {
164 hugr_mut_methods! {this, &mut **this}
165}
166
167impl<T: HugrView> HugrInternals for Rc<T> {
169 type RegionPortgraph<'p>
170 = T::RegionPortgraph<'p>
171 where
172 Self: 'p;
173
174 type Node = T::Node;
175
176 type RegionPortgraphNodes = T::RegionPortgraphNodes;
177
178 hugr_internal_methods! {this, this.as_ref()}
179}
180impl<T: HugrView> HugrView for Rc<T> {
181 hugr_view_methods! {this, this.as_ref()}
182}
183
184impl<T: HugrView> HugrInternals for Arc<T> {
186 type RegionPortgraph<'p>
187 = T::RegionPortgraph<'p>
188 where
189 Self: 'p;
190
191 type Node = T::Node;
192
193 type RegionPortgraphNodes = T::RegionPortgraphNodes;
194
195 hugr_internal_methods! {this, this.as_ref()}
196}
197impl<T: HugrView> HugrView for Arc<T> {
198 hugr_view_methods! {this, this.as_ref()}
199}
200
201impl<T: HugrView> HugrInternals for Box<T> {
203 type RegionPortgraph<'p>
204 = T::RegionPortgraph<'p>
205 where
206 Self: 'p;
207
208 type Node = T::Node;
209
210 type RegionPortgraphNodes = T::RegionPortgraphNodes;
211
212 hugr_internal_methods! {this, this.as_ref()}
213}
214impl<T: HugrView> HugrView for Box<T> {
215 hugr_view_methods! {this, this.as_ref()}
216}
217impl<T: HugrMutInternals> HugrMutInternals for Box<T> {
218 hugr_mut_internal_methods! {this, this.as_mut()}
219}
220impl<T: HugrMut> HugrMut for Box<T> {
221 hugr_mut_methods! {this, this.as_mut()}
222}
223
224impl<T: HugrView + ToOwned> HugrInternals for Cow<'_, T> {
226 type RegionPortgraph<'p>
227 = T::RegionPortgraph<'p>
228 where
229 Self: 'p;
230
231 type Node = T::Node;
232
233 type RegionPortgraphNodes = T::RegionPortgraphNodes;
234
235 hugr_internal_methods! {this, this.as_ref()}
236}
237impl<T: HugrView + ToOwned> HugrView for Cow<'_, T> {
238 hugr_view_methods! {this, this.as_ref()}
239}
240impl<T> HugrMutInternals for Cow<'_, T>
241where
242 T: HugrMutInternals + ToOwned,
243 <T as ToOwned>::Owned: HugrMutInternals<Node = T::Node>,
244{
245 hugr_mut_internal_methods! {this, this.to_mut()}
246}
247impl<T> HugrMut for Cow<'_, T>
248where
249 T: HugrMut + ToOwned,
250 <T as ToOwned>::Owned: HugrMut<Node = T::Node>,
251{
252 hugr_mut_methods! {this, this.to_mut()}
253}
254
255#[cfg(test)]
256mod test {
257 use std::{rc::Rc, sync::Arc};
258
259 use crate::{Hugr, HugrView};
260
261 struct ViewWrapper<H>(H);
262 impl<H: HugrView> ViewWrapper<H> {
263 fn nodes(&self) -> impl Iterator<Item = H::Node> + '_ {
264 self.0.nodes()
265 }
266 }
267
268 #[test]
269 fn test_refs_to_view() {
270 let h = Hugr::default();
271 let v = ViewWrapper(&h);
272 let c = h.nodes().count();
273 assert_eq!(v.nodes().count(), c);
274
275 let v2 = ViewWrapper(h.with_entrypoint(h.entrypoint()));
276 assert_eq!(v2.nodes().count(), v.nodes().count());
277 assert_eq!(ViewWrapper(&v2.0).nodes().count(), v.nodes().count());
278
279 let vh = ViewWrapper(h);
280 assert_eq!(vh.nodes().count(), c);
281 let h: Hugr = vh.0;
282 assert_eq!(h.nodes().count(), c);
283
284 let vb = ViewWrapper(Box::new(&h));
285 assert_eq!(vb.nodes().count(), c);
286 let va = ViewWrapper(Arc::new(h));
287 assert_eq!(va.nodes().count(), c);
288 let h = Arc::try_unwrap(va.0).unwrap();
289 let vr = Rc::new(&h);
290 assert_eq!(ViewWrapper(&vr).nodes().count(), h.nodes().count());
291 }
292}