summaryrefslogtreecommitdiff
path: root/vendor/petgraph/src/adj.rs
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-15 16:37:08 -0600
committermo khan <mo@mokhan.ca>2025-07-17 16:30:22 -0600
commit45df4d0d9b577fecee798d672695fe24ff57fb1b (patch)
tree1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/petgraph/src/adj.rs
parentf94f79608393d4ab127db63cc41668445ef6b243 (diff)
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based authorization system with SpiceDB's relation-based authorization. Key changes: - Migrate from Rust to Go implementation - Replace Cedar policies with SpiceDB schema and relationships - Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks - Update build system and dependencies for Go ecosystem - Maintain Envoy integration for external authorization This change enables more flexible permission modeling through SpiceDB's Google Zanzibar inspired relation-based system, supporting complex hierarchical permissions that were difficult to express in Cedar. Breaking change: Existing Cedar policies and Rust-based configuration will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/petgraph/src/adj.rs')
-rw-r--r--vendor/petgraph/src/adj.rs653
1 files changed, 0 insertions, 653 deletions
diff --git a/vendor/petgraph/src/adj.rs b/vendor/petgraph/src/adj.rs
deleted file mode 100644
index 0d107bfc..00000000
--- a/vendor/petgraph/src/adj.rs
+++ /dev/null
@@ -1,653 +0,0 @@
-//! Simple adjacency list.
-use crate::data::{Build, DataMap, DataMapMut};
-use crate::iter_format::NoPretty;
-use crate::visit::{
- self, EdgeCount, EdgeRef, GetAdjacencyMatrix, IntoEdgeReferences, IntoNeighbors, NodeCount,
-};
-use fixedbitset::FixedBitSet;
-use std::fmt;
-use std::ops::Range;
-
-#[doc(no_inline)]
-pub use crate::graph::{DefaultIx, IndexType};
-
-/// Adjacency list node index type, a plain integer.
-pub type NodeIndex<Ix = DefaultIx> = Ix;
-
-/// Adjacency list edge index type, a pair of integers.
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct EdgeIndex<Ix = DefaultIx>
-where
- Ix: IndexType,
-{
- /// Source of the edge.
- from: NodeIndex<Ix>,
- /// Index of the sucessor in the successor list.
- successor_index: usize,
-}
-
-iterator_wrap! {
-impl (Iterator) for
-/// An Iterator over the indices of the outgoing edges from a node.
-///
-/// It does not borrow the graph during iteration.
-#[derive(Debug, Clone)]
-struct OutgoingEdgeIndices <Ix> where { Ix: IndexType }
-item: EdgeIndex<Ix>,
-iter: std::iter::Map<std::iter::Zip<Range<usize>, std::iter::Repeat<NodeIndex<Ix>>>, fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix>>,
-}
-
-/// Weighted sucessor
-#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
-struct WSuc<E, Ix: IndexType> {
- /// Index of the sucessor.
- suc: Ix,
- /// Weight of the edge to `suc`.
- weight: E,
-}
-
-/// One row of the adjacency list.
-type Row<E, Ix> = Vec<WSuc<E, Ix>>;
-type RowIter<'a, E, Ix> = std::slice::Iter<'a, WSuc<E, Ix>>;
-
-iterator_wrap! {
-impl (Iterator DoubleEndedIterator ExactSizeIterator) for
-/// An iterator over the indices of the neighbors of a node.
-#[derive(Debug, Clone)]
-struct Neighbors<'a, E, Ix> where { Ix: IndexType }
-item: NodeIndex<Ix>,
-iter: std::iter::Map<RowIter<'a, E, Ix>, fn(&WSuc<E, Ix>) -> NodeIndex<Ix>>,
-}
-
-/// A reference to an edge of the graph.
-#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
-pub struct EdgeReference<'a, E, Ix: IndexType> {
- /// index of the edge
- id: EdgeIndex<Ix>,
- /// a reference to the corresponding item in the adjacency list
- edge: &'a WSuc<E, Ix>,
-}
-
-impl<E, Ix: IndexType> Copy for EdgeReference<'_, E, Ix> {}
-impl<E, Ix: IndexType> Clone for EdgeReference<'_, E, Ix> {
- fn clone(&self) -> Self {
- *self
- }
-}
-
-impl<E, Ix: IndexType> visit::EdgeRef for EdgeReference<'_, E, Ix> {
- type NodeId = NodeIndex<Ix>;
- type EdgeId = EdgeIndex<Ix>;
- type Weight = E;
- fn source(&self) -> Self::NodeId {
- self.id.from
- }
- fn target(&self) -> Self::NodeId {
- self.edge.suc
- }
- fn id(&self) -> Self::EdgeId {
- self.id
- }
- fn weight(&self) -> &Self::Weight {
- &self.edge.weight
- }
-}
-
-#[derive(Debug, Clone)]
-pub struct EdgeIndices<'a, E, Ix: IndexType> {
- rows: std::iter::Enumerate<std::slice::Iter<'a, Row<E, Ix>>>,
- row_index: usize,
- row_len: usize,
- cur: usize,
-}
-
-impl<E, Ix: IndexType> Iterator for EdgeIndices<'_, E, Ix> {
- type Item = EdgeIndex<Ix>;
- fn next(&mut self) -> Option<EdgeIndex<Ix>> {
- loop {
- if self.cur < self.row_len {
- let res = self.cur;
- self.cur += 1;
- return Some(EdgeIndex {
- from: Ix::new(self.row_index),
- successor_index: res,
- });
- } else {
- match self.rows.next() {
- Some((index, row)) => {
- self.row_index = index;
- self.cur = 0;
- self.row_len = row.len();
- }
- None => return None,
- }
- }
- }
- }
-}
-
-iterator_wrap! {
- impl (Iterator DoubleEndedIterator ExactSizeIterator) for
- /// An iterator over all node indices in the graph.
- #[derive(Debug, Clone)]
- struct NodeIndices <Ix> where {}
- item: Ix,
- iter: std::iter::Map<Range<usize>, fn(usize) -> Ix>,
-}
-
-/// An adjacency list with labeled edges.
-///
-/// Can be interpreted as a directed graph
-/// with unweighted nodes.
-///
-/// This is the most simple adjacency list you can imagine. [`Graph`](../graph/struct.Graph.html), in contrast,
-/// maintains both the list of successors and predecessors for each node,
-/// which is a different trade-off.
-///
-/// Allows parallel edges and self-loops.
-///
-/// This data structure is append-only (except for [`clear`](#method.clear)), so indices
-/// returned at some point for a given graph will stay valid with this same
-/// graph until it is dropped or [`clear`](#method.clear) is called.
-///
-/// Space consumption: **O(|E|)**.
-#[derive(Clone, Default)]
-pub struct List<E, Ix = DefaultIx>
-where
- Ix: IndexType,
-{
- suc: Vec<Row<E, Ix>>,
-}
-
-impl<E, Ix: IndexType> List<E, Ix> {
- /// Creates a new, empty adjacency list.
- pub fn new() -> List<E, Ix> {
- List { suc: Vec::new() }
- }
-
- /// Creates a new, empty adjacency list tailored for `nodes` nodes.
- pub fn with_capacity(nodes: usize) -> List<E, Ix> {
- List {
- suc: Vec::with_capacity(nodes),
- }
- }
-
- /// Removes all nodes and edges from the list.
- pub fn clear(&mut self) {
- self.suc.clear()
- }
-
- /// Returns the number of edges in the list
- ///
- /// Computes in **O(|V|)** time.
- pub fn edge_count(&self) -> usize {
- self.suc.iter().map(|x| x.len()).sum()
- }
-
- /// Adds a new node to the list. This allocates a new `Vec` and then should
- /// run in amortized **O(1)** time.
- pub fn add_node(&mut self) -> NodeIndex<Ix> {
- let i = self.suc.len();
- self.suc.push(Vec::new());
- Ix::new(i)
- }
-
- /// Adds a new node to the list. This allocates a new `Vec` and then should
- /// run in amortized **O(1)** time.
- pub fn add_node_with_capacity(&mut self, successors: usize) -> NodeIndex<Ix> {
- let i = self.suc.len();
- self.suc.push(Vec::with_capacity(successors));
- Ix::new(i)
- }
-
- /// Adds a new node to the list by giving its list of successors and the corresponding
- /// weigths.
- pub fn add_node_from_edges<I: Iterator<Item = (NodeIndex<Ix>, E)>>(
- &mut self,
- edges: I,
- ) -> NodeIndex<Ix> {
- let i = self.suc.len();
- self.suc
- .push(edges.map(|(suc, weight)| WSuc { suc, weight }).collect());
- Ix::new(i)
- }
-
- /// Add an edge from `a` to `b` to the graph, with its associated
- /// data `weight`.
- ///
- /// Return the index of the new edge.
- ///
- /// Computes in **O(1)** time.
- ///
- /// **Panics** if the source node does not exist.<br>
- ///
- /// **Note:** `List` allows adding parallel (“duplicate”) edges. If you want
- /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
- pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
- if b.index() >= self.suc.len() {
- panic!(
- "{} is not a valid node index for a {} nodes adjacency list",
- b.index(),
- self.suc.len()
- );
- }
- let row = &mut self.suc[a.index()];
- let rank = row.len();
- row.push(WSuc { suc: b, weight });
- EdgeIndex {
- from: a,
- successor_index: rank,
- }
- }
-
- fn get_edge(&self, e: EdgeIndex<Ix>) -> Option<&WSuc<E, Ix>> {
- self.suc
- .get(e.from.index())
- .and_then(|row| row.get(e.successor_index))
- }
-
- fn get_edge_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut WSuc<E, Ix>> {
- self.suc
- .get_mut(e.from.index())
- .and_then(|row| row.get_mut(e.successor_index))
- }
-
- /// Accesses the source and target of edge `e`
- ///
- /// Computes in **O(1)**
- pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
- self.get_edge(e).map(|x| (e.from, x.suc))
- }
-
- pub fn edge_indices_from(&self, a: NodeIndex<Ix>) -> OutgoingEdgeIndices<Ix> {
- let proj: fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix> =
- |(successor_index, from)| EdgeIndex {
- from,
- successor_index,
- };
- let iter = (0..(self.suc[a.index()].len()))
- .zip(std::iter::repeat(a))
- .map(proj);
- OutgoingEdgeIndices { iter }
- }
-
- /// Lookups whether there is an edge from `a` to `b`.
- ///
- /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
- pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
- match self.suc.get(a.index()) {
- None => false,
- Some(row) => row.iter().any(|x| x.suc == b),
- }
- }
-
- /// Lookups whether there is an edge from `a` to `b`.
- ///
- /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
- pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
- self.suc.get(a.index()).and_then(|row| {
- row.iter()
- .enumerate()
- .find(|(_, x)| x.suc == b)
- .map(|(i, _)| EdgeIndex {
- from: a,
- successor_index: i,
- })
- })
- }
-
- /// Returns an iterator over all node indices of the graph.
- ///
- /// Consuming the whole iterator take **O(|V|)**.
- pub fn node_indices(&self) -> NodeIndices<Ix> {
- NodeIndices {
- iter: (0..self.suc.len()).map(Ix::new),
- }
- }
-
- /// Returns an iterator over all edge indices of the graph.
- ///
- /// Consuming the whole iterator take **O(|V| + |E|)**.
- pub fn edge_indices(&self) -> EdgeIndices<E, Ix> {
- EdgeIndices {
- rows: self.suc.iter().enumerate(),
- row_index: 0,
- row_len: 0,
- cur: 0,
- }
- }
-}
-
-/// A very simple adjacency list with no node or label weights.
-pub type UnweightedList<Ix> = List<(), Ix>;
-
-impl<E, Ix: IndexType> Build for List<E, Ix> {
- /// Adds a new node to the list. This allocates a new `Vec` and then should
- /// run in amortized **O(1)** time.
- fn add_node(&mut self, _weight: ()) -> NodeIndex<Ix> {
- self.add_node()
- }
-
- /// Add an edge from `a` to `b` to the graph, with its associated
- /// data `weight`.
- ///
- /// Return the index of the new edge.
- ///
- /// Computes in **O(1)** time.
- ///
- /// **Panics** if the source node does not exist.<br>
- ///
- /// **Note:** `List` allows adding parallel (“duplicate”) edges. If you want
- /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
- fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> Option<EdgeIndex<Ix>> {
- Some(self.add_edge(a, b, weight))
- }
-
- /// Updates or adds an edge from `a` to `b` to the graph, with its associated
- /// data `weight`.
- ///
- /// Return the index of the new edge.
- ///
- /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
- ///
- /// **Panics** if the source node does not exist.<br>
- fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
- let row = &mut self.suc[a.index()];
- for (i, info) in row.iter_mut().enumerate() {
- if info.suc == b {
- info.weight = weight;
- return EdgeIndex {
- from: a,
- successor_index: i,
- };
- }
- }
- let rank = row.len();
- row.push(WSuc { suc: b, weight });
- EdgeIndex {
- from: a,
- successor_index: rank,
- }
- }
-}
-
-impl<E, Ix> fmt::Debug for EdgeReferences<'_, E, Ix>
-where
- E: fmt::Debug,
- Ix: IndexType,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let mut edge_list = f.debug_list();
- let iter: Self = self.clone();
- for e in iter {
- if std::mem::size_of::<E>() != 0 {
- edge_list.entry(&(
- NoPretty((e.source().index(), e.target().index())),
- e.weight(),
- ));
- } else {
- edge_list.entry(&NoPretty((e.source().index(), e.target().index())));
- }
- }
- edge_list.finish()
- }
-}
-
-impl<E, Ix> fmt::Debug for List<E, Ix>
-where
- E: fmt::Debug,
- Ix: IndexType,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let mut fmt_struct = f.debug_struct("adj::List");
- fmt_struct.field("node_count", &self.node_count());
- fmt_struct.field("edge_count", &self.edge_count());
- if self.edge_count() > 0 {
- fmt_struct.field("edges", &self.edge_references());
- }
- fmt_struct.finish()
- }
-}
-
-impl<E, Ix> visit::GraphBase for List<E, Ix>
-where
- Ix: IndexType,
-{
- type NodeId = NodeIndex<Ix>;
- type EdgeId = EdgeIndex<Ix>;
-}
-
-impl<E, Ix> visit::Visitable for List<E, Ix>
-where
- Ix: IndexType,
-{
- type Map = FixedBitSet;
- fn visit_map(&self) -> FixedBitSet {
- FixedBitSet::with_capacity(self.node_count())
- }
- fn reset_map(&self, map: &mut Self::Map) {
- map.clear();
- map.grow(self.node_count());
- }
-}
-
-impl<E, Ix: IndexType> visit::IntoNodeIdentifiers for &List<E, Ix> {
- type NodeIdentifiers = NodeIndices<Ix>;
- fn node_identifiers(self) -> NodeIndices<Ix> {
- self.node_indices()
- }
-}
-
-impl<Ix: IndexType> visit::NodeRef for NodeIndex<Ix> {
- type NodeId = NodeIndex<Ix>;
- type Weight = ();
- fn id(&self) -> Self::NodeId {
- *self
- }
- fn weight(&self) -> &Self::Weight {
- &()
- }
-}
-
-impl<Ix: IndexType, E> visit::IntoNodeReferences for &List<E, Ix> {
- type NodeRef = NodeIndex<Ix>;
- type NodeReferences = NodeIndices<Ix>;
- fn node_references(self) -> Self::NodeReferences {
- self.node_indices()
- }
-}
-
-impl<E, Ix: IndexType> visit::Data for List<E, Ix> {
- type NodeWeight = ();
- type EdgeWeight = E;
-}
-
-impl<'a, E, Ix: IndexType> IntoNeighbors for &'a List<E, Ix> {
- type Neighbors = Neighbors<'a, E, Ix>;
- /// Returns an iterator of all nodes with an edge starting from `a`.
- /// Panics if `a` is out of bounds.
- /// Use [`List::edge_indices_from`] instead if you do not want to borrow the adjacency list while
- /// iterating.
- fn neighbors(self, a: NodeIndex<Ix>) -> Self::Neighbors {
- let proj: fn(&WSuc<E, Ix>) -> NodeIndex<Ix> = |x| x.suc;
- let iter = self.suc[a.index()].iter().map(proj);
- Neighbors { iter }
- }
-}
-
-type SomeIter<'a, E, Ix> = std::iter::Map<
- std::iter::Zip<std::iter::Enumerate<RowIter<'a, E, Ix>>, std::iter::Repeat<Ix>>,
- fn(((usize, &'a WSuc<E, Ix>), Ix)) -> EdgeReference<'a, E, Ix>,
->;
-
-iterator_wrap! {
-impl (Iterator) for
-/// An iterator over the [`EdgeReference`] of all the edges of the graph.
-struct EdgeReferences<'a, E, Ix> where { Ix: IndexType }
-item: EdgeReference<'a, E, Ix>,
-iter: std::iter::FlatMap<
- std::iter::Enumerate<
- std::slice::Iter<'a, Row<E, Ix>>
- >,
- SomeIter<'a, E, Ix>,
- fn(
- (usize, &'a Vec<WSuc<E, Ix>>)
- ) -> SomeIter<'a, E, Ix>,
->,
-}
-
-impl<E, Ix: IndexType> Clone for EdgeReferences<'_, E, Ix> {
- fn clone(&self) -> Self {
- EdgeReferences {
- iter: self.iter.clone(),
- }
- }
-}
-
-fn proj1<E, Ix: IndexType>(
- ((successor_index, edge), from): ((usize, &WSuc<E, Ix>), Ix),
-) -> EdgeReference<E, Ix> {
- let id = EdgeIndex {
- from,
- successor_index,
- };
- EdgeReference { id, edge }
-}
-fn proj2<E, Ix: IndexType>((row_index, row): (usize, &Vec<WSuc<E, Ix>>)) -> SomeIter<E, Ix> {
- row.iter()
- .enumerate()
- .zip(std::iter::repeat(Ix::new(row_index)))
- .map(proj1 as _)
-}
-
-impl<'a, Ix: IndexType, E> visit::IntoEdgeReferences for &'a List<E, Ix> {
- type EdgeRef = EdgeReference<'a, E, Ix>;
- type EdgeReferences = EdgeReferences<'a, E, Ix>;
- fn edge_references(self) -> Self::EdgeReferences {
- let iter = self.suc.iter().enumerate().flat_map(proj2 as _);
- EdgeReferences { iter }
- }
-}
-
-iterator_wrap! {
-impl (Iterator) for
-/// Iterator over the [`EdgeReference`] of the outgoing edges from a node.
-#[derive(Debug, Clone)]
-struct OutgoingEdgeReferences<'a, E, Ix> where { Ix: IndexType }
-item: EdgeReference<'a, E, Ix>,
-iter: SomeIter<'a, E, Ix>,
-}
-
-impl<'a, Ix: IndexType, E> visit::IntoEdges for &'a List<E, Ix> {
- type Edges = OutgoingEdgeReferences<'a, E, Ix>;
- fn edges(self, a: Self::NodeId) -> Self::Edges {
- let iter = self.suc[a.index()]
- .iter()
- .enumerate()
- .zip(std::iter::repeat(a))
- .map(proj1 as _);
- OutgoingEdgeReferences { iter }
- }
-}
-
-impl<E, Ix: IndexType> visit::GraphProp for List<E, Ix> {
- type EdgeType = crate::Directed;
- fn is_directed(&self) -> bool {
- true
- }
-}
-
-impl<E, Ix: IndexType> NodeCount for List<E, Ix> {
- /// Returns the number of nodes in the list
- ///
- /// Computes in **O(1)** time.
- fn node_count(&self) -> usize {
- self.suc.len()
- }
-}
-
-impl<E, Ix: IndexType> EdgeCount for List<E, Ix> {
- /// Returns the number of edges in the list
- ///
- /// Computes in **O(|V|)** time.
- fn edge_count(&self) -> usize {
- List::edge_count(self)
- }
-}
-
-impl<E, Ix: IndexType> visit::NodeIndexable for List<E, Ix> {
- fn node_bound(&self) -> usize {
- self.node_count()
- }
- #[inline]
- fn to_index(&self, a: Self::NodeId) -> usize {
- a.index()
- }
- #[inline]
- fn from_index(&self, i: usize) -> Self::NodeId {
- Ix::new(i)
- }
-}
-
-impl<E, Ix: IndexType> visit::NodeCompactIndexable for List<E, Ix> {}
-
-impl<E, Ix: IndexType> DataMap for List<E, Ix> {
- fn node_weight(&self, n: Self::NodeId) -> Option<&()> {
- if n.index() < self.suc.len() {
- Some(&())
- } else {
- None
- }
- }
-
- /// Accesses the weight of edge `e`
- ///
- /// Computes in **O(1)**
- fn edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E> {
- self.get_edge(e).map(|x| &x.weight)
- }
-}
-
-impl<E, Ix: IndexType> DataMapMut for List<E, Ix> {
- fn node_weight_mut(&mut self, n: Self::NodeId) -> Option<&mut ()> {
- if n.index() < self.suc.len() {
- // A hack to produce a &'static mut ()
- // It does not actually allocate according to godbolt
- let b = Box::new(());
- Some(Box::leak(b))
- } else {
- None
- }
- }
- /// Accesses the weight of edge `e`
- ///
- /// Computes in **O(1)**
- fn edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E> {
- self.get_edge_mut(e).map(|x| &mut x.weight)
- }
-}
-
-/// The adjacency matrix for **List** is a bitmap that's computed by
-/// `.adjacency_matrix()`.
-impl<E, Ix> GetAdjacencyMatrix for List<E, Ix>
-where
- Ix: IndexType,
-{
- type AdjMatrix = FixedBitSet;
-
- fn adjacency_matrix(&self) -> FixedBitSet {
- let n = self.node_count();
- let mut matrix = FixedBitSet::with_capacity(n * n);
- for edge in self.edge_references() {
- let i = edge.source().index() * n + edge.target().index();
- matrix.put(i);
- }
- matrix
- }
-
- fn is_adjacent(&self, matrix: &FixedBitSet, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
- let n = self.node_count();
- let index = n * a.index() + b.index();
- matrix.contains(index)
- }
-}