@@ -160,14 +160,6 @@ impl<H: HugrView> ResourceScope<H> {
160160 Some ( * port_map. get ( port) )
161161 }
162162
163- /// Get the [`ResourceId`] for a given port.
164- ///
165- /// Return None if the port is not a resource port.
166- pub fn get_resource_id ( & self , node : H :: Node , port : impl Into < Port > ) -> Option < ResourceId > {
167- let unit = self . get_circuit_unit ( node, port) ?;
168- unit. as_resource ( )
169- }
170-
171163 /// Get all [`CircuitUnit`]s for either the incoming or outgoing ports of a
172164 /// node.
173165 pub fn get_circuit_units_slice (
@@ -179,15 +171,47 @@ impl<H: HugrView> ResourceScope<H> {
179171 Some ( port_map. get_slice ( direction) )
180172 }
181173
182- /// Get the port of node on the given resource path .
174+ /// Get the ports of node with the given opvalue in the given direction .
183175 ///
184176 /// The returned port will have the direction `dir`.
185- pub fn get_port ( & self , node : H :: Node , resource_id : ResourceId , dir : Direction ) -> Option < Port > {
186- let units = self . get_circuit_units_slice ( node, dir) ?;
187- let offset = units
188- . iter ( )
189- . position ( |unit| unit. as_resource ( ) == Some ( resource_id) ) ?;
190- Some ( Port :: new ( dir, offset) )
177+ pub fn get_ports (
178+ & self ,
179+ node : H :: Node ,
180+ unit : impl Into < CircuitUnit < H :: Node > > ,
181+ dir : Direction ,
182+ ) -> impl Iterator < Item = Port > + ' _ {
183+ let exp_unit = unit. into ( ) ;
184+ let units = self . get_circuit_units_slice ( node, dir) ;
185+ let offsets = units
186+ . into_iter ( )
187+ . flatten ( )
188+ . positions ( move |unit| unit == & exp_unit) ;
189+ offsets. map ( move |offset| Port :: new ( dir, offset) )
190+ }
191+
192+ /// Get the port of node with the given resource in the given direction.
193+ pub fn get_resource_port (
194+ & self ,
195+ node : H :: Node ,
196+ resource_id : ResourceId ,
197+ dir : Direction ,
198+ ) -> Option < Port > {
199+ self . get_ports ( node, resource_id, dir)
200+ . at_most_one ( )
201+ . ok ( )
202+ . expect ( "linear resource" )
203+ }
204+
205+ /// Get the resource ID at the given port of the given node.
206+ pub fn get_resource_id ( & self , node : H :: Node , port : impl Into < Port > ) -> Option < ResourceId > {
207+ let unit = self . get_circuit_unit ( node, port) ?;
208+ unit. as_resource ( )
209+ }
210+
211+ /// Get the copyable wire at the given port of the given node.
212+ pub fn get_copyable_wire ( & self , node : H :: Node , port : impl Into < Port > ) -> Option < Wire < H :: Node > > {
213+ let unit = self . get_circuit_unit ( node, port) ?;
214+ unit. as_copyable_wire ( )
191215 }
192216
193217 /// Get the position of the given node.
@@ -215,24 +239,21 @@ impl<H: HugrView> ResourceScope<H> {
215239 . filter_map ( |unit| unit. as_resource ( ) )
216240 }
217241
218- /// All resource IDs on the ports of `node`, in both directions.
219- pub fn get_all_resources ( & self , node : H :: Node ) -> Vec < ResourceId > {
242+ /// All resource IDs on the ports of `node`, in both directions, in the
243+ /// order that they appear along the ports of `node`.
244+ pub fn get_all_resources ( & self , node : H :: Node ) -> impl Iterator < Item = ResourceId > + ' _ {
220245 let in_resources = self . get_resources ( node, Direction :: Incoming ) ;
221246 let out_resources = self . get_resources ( node, Direction :: Outgoing ) ;
222- let mut all_resources = in_resources. chain ( out_resources) . collect_vec ( ) ;
223- all_resources. sort_unstable ( ) ;
224- all_resources. dedup ( ) ;
225- all_resources. shrink_to_fit ( ) ;
226- all_resources
247+ in_resources. chain ( out_resources) . unique ( )
227248 }
228249
229250 /// Whether the given node is the first node on the path of the given
230251 /// resource.
231252 pub fn is_resource_start ( & self , node : H :: Node , resource_id : ResourceId ) -> bool {
232- self . get_port ( node, resource_id, Direction :: Outgoing )
253+ self . get_resource_port ( node, resource_id, Direction :: Outgoing )
233254 . is_some ( )
234255 && self
235- . get_port ( node, resource_id, Direction :: Incoming )
256+ . get_resource_port ( node, resource_id, Direction :: Incoming )
236257 . is_none ( )
237258 }
238259
@@ -246,7 +267,7 @@ impl<H: HugrView> ResourceScope<H> {
246267 }
247268
248269 /// All copyable wires on the ports of `node` in the given direction.
249- pub fn get_copyable_wires (
270+ pub fn all_copyable_wires (
250271 & self ,
251272 node : H :: Node ,
252273 dir : Direction ,
@@ -258,6 +279,18 @@ impl<H: HugrView> ResourceScope<H> {
258279 } )
259280 }
260281
282+ /// All ports of `node` in the given direction that are copyable.
283+ pub fn get_copyable_ports (
284+ & self ,
285+ node : H :: Node ,
286+ dir : Direction ,
287+ ) -> impl Iterator < Item = Port > + ' _ {
288+ let units = self . get_circuit_units_slice ( node, dir) ;
289+ let ports = self . hugr ( ) . node_ports ( node, dir) ;
290+ let units_ports = units. into_iter ( ) . flatten ( ) . zip ( ports) ;
291+ units_ports. filter_map ( |( unit, port) | unit. is_copyable ( ) . then_some ( port) )
292+ }
293+
261294 /// Iterate over the nodes on the resource path starting from the given
262295 /// node in the given direction.
263296 pub fn resource_path_iter (
@@ -267,7 +300,7 @@ impl<H: HugrView> ResourceScope<H> {
267300 direction : Direction ,
268301 ) -> impl Iterator < Item = H :: Node > + ' _ {
269302 iter:: successors ( Some ( start_node) , move |& curr_node| {
270- let port = self . get_port ( curr_node, resource_id, direction) ?;
303+ let port = self . get_resource_port ( curr_node, resource_id, direction) ?;
271304 let ( next_node, _) = self
272305 . hugr ( )
273306 . single_linked_port ( curr_node, port)
@@ -734,11 +767,7 @@ pub(crate) mod tests {
734767 . map ( |( n, _) | n) ;
735768
736769 for h in first_hadamards {
737- let res = scope
738- . get_all_resources ( h)
739- . into_iter ( )
740- . exactly_one ( )
741- . unwrap ( ) ;
770+ let res = scope. get_all_resources ( h) . exactly_one ( ) . ok ( ) . unwrap ( ) ;
742771 let nodes_on_path = scope. resource_path_iter ( res, h, Direction :: Outgoing ) ;
743772 let pos_on_path = nodes_on_path. map ( |n| scope. get_position ( n) . unwrap ( ) ) ;
744773
0 commit comments