Skip to main content

zrx_graph/graph/operator/
adjacent.rs

1// Copyright (c) 2025-2026 Zensical and contributors
2
3// SPDX-License-Identifier: MIT
4// All contributions are certified under the DCO
5
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to
8// deal in the Software without restriction, including without limitation the
9// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10// sell copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12
13// The above copyright notice and this permission notice shall be included in
14// all copies or substantial portions of the Software.
15
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22// IN THE SOFTWARE.
23
24// ----------------------------------------------------------------------------
25
26//! Adjacent operator.
27
28use crate::graph::Graph;
29
30// ----------------------------------------------------------------------------
31// Structs
32// ----------------------------------------------------------------------------
33
34/// Adjacent nodes.
35pub struct Adjacent<'a> {
36    /// Incoming edges.
37    pub incoming: &'a [usize],
38    /// Outgoing edges.
39    pub outgoing: &'a [usize],
40}
41
42// ----------------------------------------------------------------------------
43// Implementations
44// ----------------------------------------------------------------------------
45
46impl<T> Graph<T> {
47    /// Retrieve a reference to a node and its adjacent nodes.
48    ///
49    /// # Examples
50    ///
51    /// ```
52    /// # use std::error::Error;
53    /// # fn main() -> Result<(), Box<dyn Error>> {
54    /// use zrx_graph::Graph;
55    ///
56    /// // Create graph builder and add nodes
57    /// let mut builder = Graph::builder();
58    /// let a = builder.add_node("a");
59    /// let b = builder.add_node("b");
60    /// let c = builder.add_node("c");
61    ///
62    /// // Create edges between nodes
63    /// builder.add_edge(a, b)?;
64    /// builder.add_edge(b, c)?;
65    ///
66    /// // Create graph from builder and retrieve node
67    /// let graph = builder.build();
68    ///
69    /// // Obtain reference to node and adjacent nodes
70    /// let (data, adj) = graph.adjacent(a);
71    /// # Ok(())
72    /// # }
73    /// ```
74    #[inline]
75    #[must_use]
76    pub fn adjacent(&self, node: usize) -> (&'_ T, Adjacent<'_>) {
77        let incoming = self.topology.incoming();
78        let outgoing = self.topology.outgoing();
79        (
80            &self.data[node],
81            Adjacent {
82                incoming: &incoming[node],
83                outgoing: &outgoing[node],
84            },
85        )
86    }
87
88    /// Retrieve a mutable reference to a node and its adjacent nodes.
89    ///
90    /// # Examples
91    ///
92    /// ```
93    /// # use std::error::Error;
94    /// # fn main() -> Result<(), Box<dyn Error>> {
95    /// use zrx_graph::Graph;
96    ///
97    /// // Create graph builder and add nodes
98    /// let mut builder = Graph::builder();
99    /// let a = builder.add_node("a");
100    /// let b = builder.add_node("b");
101    /// let c = builder.add_node("c");
102    ///
103    /// // Create edges between nodes
104    /// builder.add_edge(a, b)?;
105    /// builder.add_edge(b, c)?;
106    ///
107    /// // Create graph from builder and retrieve node
108    /// let mut graph = builder.build();
109    ///
110    /// // Obtain mutable reference to node and adjacent nodes
111    /// let (data, adj) = graph.adjacent_mut(a);
112    /// # Ok(())
113    /// # }
114    /// ```
115    #[inline]
116    #[must_use]
117    pub fn adjacent_mut(&mut self, node: usize) -> (&'_ mut T, Adjacent<'_>) {
118        let incoming = self.topology.incoming();
119        let outgoing = self.topology.outgoing();
120        (
121            &mut self.data[node],
122            Adjacent {
123                incoming: &incoming[node],
124                outgoing: &outgoing[node],
125            },
126        )
127    }
128}