hugr_core/hugr/views/
impls.rs

1//! Implementation of the core hugr traits for different wrappers of a `Hugr`.
2
3use std::{borrow::Cow, rc::Rc, sync::Arc};
4
5use super::HugrView;
6use crate::hugr::HugrMut;
7use crate::hugr::internal::{HugrInternals, HugrMutInternals};
8
9macro_rules! hugr_internal_methods {
10    // The extra ident here is because invocations of the macro cannot pass `self` as argument
11    ($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    // The extra ident here is because invocations of the macro cannot pass `self` as argument
24    ($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    // The extra ident here is because invocations of the macro cannot pass `self` as argument
79    ($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    // The extra ident here is because invocations of the macro cannot pass `self` as argument
101    ($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_hugr(&mut self, root: Self::Node, other: crate::Hugr) -> crate::hugr::hugrmut::InsertionResult<crate::Node, Self::Node>;
118                fn insert_region(&mut self, root: Self::Node, other: crate::Hugr, region: crate::Node) -> crate::hugr::hugrmut::InsertionResult<crate::Node, Self::Node>;
119                fn insert_from_view<Other: crate::hugr::HugrView>(&mut self, root: Self::Node, other: &Other) -> crate::hugr::hugrmut::InsertionResult<Other::Node, Self::Node>;
120                fn insert_subgraph<Other: crate::hugr::HugrView>(&mut self, root: Self::Node, other: &Other, subgraph: &crate::hugr::views::SiblingSubgraph<Other::Node>) -> std::collections::HashMap<Other::Node, Self::Node>;
121                fn use_extension(&mut self, extension: impl Into<std::sync::Arc<crate::extension::Extension>>);
122                fn use_extensions<Reg>(&mut self, registry: impl IntoIterator<Item = Reg>) where crate::extension::ExtensionRegistry: Extend<Reg>;
123            }
124        }
125    };
126}
127pub(crate) use hugr_mut_methods;
128
129// -------- Immutable borrow
130impl<T: HugrView> HugrInternals for &T {
131    type RegionPortgraph<'p>
132        = T::RegionPortgraph<'p>
133    where
134        Self: 'p;
135
136    type Node = T::Node;
137
138    type RegionPortgraphNodes = T::RegionPortgraphNodes;
139
140    hugr_internal_methods! {this, *this}
141}
142impl<T: HugrView> HugrView for &T {
143    hugr_view_methods! {this, *this}
144}
145
146// -------- Mutable borrow
147impl<T: HugrView> HugrInternals for &mut T {
148    type RegionPortgraph<'p>
149        = T::RegionPortgraph<'p>
150    where
151        Self: 'p;
152
153    type Node = T::Node;
154
155    type RegionPortgraphNodes = T::RegionPortgraphNodes;
156
157    hugr_internal_methods! {this, &**this}
158}
159impl<T: HugrView> HugrView for &mut T {
160    hugr_view_methods! {this, &**this}
161}
162impl<T: HugrMutInternals> HugrMutInternals for &mut T {
163    hugr_mut_internal_methods! {this, &mut **this}
164}
165impl<T: HugrMut> HugrMut for &mut T {
166    hugr_mut_methods! {this, &mut **this}
167}
168
169// -------- Rc
170impl<T: HugrView> HugrInternals for Rc<T> {
171    type RegionPortgraph<'p>
172        = T::RegionPortgraph<'p>
173    where
174        Self: 'p;
175
176    type Node = T::Node;
177
178    type RegionPortgraphNodes = T::RegionPortgraphNodes;
179
180    hugr_internal_methods! {this, this.as_ref()}
181}
182impl<T: HugrView> HugrView for Rc<T> {
183    hugr_view_methods! {this, this.as_ref()}
184}
185
186// -------- Arc
187impl<T: HugrView> HugrInternals for Arc<T> {
188    type RegionPortgraph<'p>
189        = T::RegionPortgraph<'p>
190    where
191        Self: 'p;
192
193    type Node = T::Node;
194
195    type RegionPortgraphNodes = T::RegionPortgraphNodes;
196
197    hugr_internal_methods! {this, this.as_ref()}
198}
199impl<T: HugrView> HugrView for Arc<T> {
200    hugr_view_methods! {this, this.as_ref()}
201}
202
203// -------- Box
204impl<T: HugrView> HugrInternals for Box<T> {
205    type RegionPortgraph<'p>
206        = T::RegionPortgraph<'p>
207    where
208        Self: 'p;
209
210    type Node = T::Node;
211
212    type RegionPortgraphNodes = T::RegionPortgraphNodes;
213
214    hugr_internal_methods! {this, this.as_ref()}
215}
216impl<T: HugrView> HugrView for Box<T> {
217    hugr_view_methods! {this, this.as_ref()}
218}
219impl<T: HugrMutInternals> HugrMutInternals for Box<T> {
220    hugr_mut_internal_methods! {this, this.as_mut()}
221}
222impl<T: HugrMut> HugrMut for Box<T> {
223    hugr_mut_methods! {this, this.as_mut()}
224}
225
226// -------- Cow
227impl<T: HugrView + ToOwned> HugrInternals for Cow<'_, T> {
228    type RegionPortgraph<'p>
229        = T::RegionPortgraph<'p>
230    where
231        Self: 'p;
232
233    type Node = T::Node;
234
235    type RegionPortgraphNodes = T::RegionPortgraphNodes;
236
237    hugr_internal_methods! {this, this.as_ref()}
238}
239impl<T: HugrView + ToOwned> HugrView for Cow<'_, T> {
240    hugr_view_methods! {this, this.as_ref()}
241}
242impl<T> HugrMutInternals for Cow<'_, T>
243where
244    T: HugrMutInternals + ToOwned,
245    <T as ToOwned>::Owned: HugrMutInternals<Node = T::Node>,
246{
247    hugr_mut_internal_methods! {this, this.to_mut()}
248}
249impl<T> HugrMut for Cow<'_, T>
250where
251    T: HugrMut + ToOwned,
252    <T as ToOwned>::Owned: HugrMut<Node = T::Node>,
253{
254    hugr_mut_methods! {this, this.to_mut()}
255}
256
257#[cfg(test)]
258mod test {
259    use std::{rc::Rc, sync::Arc};
260
261    use crate::{Hugr, HugrView};
262
263    struct ViewWrapper<H>(H);
264    impl<H: HugrView> ViewWrapper<H> {
265        fn nodes(&self) -> impl Iterator<Item = H::Node> + '_ {
266            self.0.nodes()
267        }
268    }
269
270    #[test]
271    fn test_refs_to_view() {
272        let h = Hugr::default();
273        let v = ViewWrapper(&h);
274        let c = h.nodes().count();
275        assert_eq!(v.nodes().count(), c);
276
277        let v2 = ViewWrapper(h.with_entrypoint(h.entrypoint()));
278        assert_eq!(v2.nodes().count(), v.nodes().count());
279        assert_eq!(ViewWrapper(&v2.0).nodes().count(), v.nodes().count());
280
281        let vh = ViewWrapper(h);
282        assert_eq!(vh.nodes().count(), c);
283        let h: Hugr = vh.0;
284        assert_eq!(h.nodes().count(), c);
285
286        let vb = ViewWrapper(Box::new(&h));
287        assert_eq!(vb.nodes().count(), c);
288        let va = ViewWrapper(Arc::new(h));
289        assert_eq!(va.nodes().count(), c);
290        let h = Arc::try_unwrap(va.0).unwrap();
291        let vr = Rc::new(&h);
292        assert_eq!(ViewWrapper(&vr).nodes().count(), h.nodes().count());
293    }
294}