fuchsia_inspect_contrib/graph/
vertex.rs1use super::edge::WeakEdgeRef;
6use super::{Edge, EdgeMetadata, VertexId};
7use fuchsia_inspect as inspect;
8use std::collections::BTreeMap;
9
10#[derive(Debug)]
13pub struct Vertex<M: VertexMetadata> {
14 _node: inspect::Node,
15 id: M::Id,
16 metadata: M,
17 incoming_edges: BTreeMap<u64, WeakEdgeRef<M::EdgeMeta>>,
18 outgoing_edges: BTreeMap<u64, WeakEdgeRef<M::EdgeMeta>>,
19 pub(crate) outgoing_edges_node: inspect::Node,
20}
21
22pub trait VertexMetadata {
24 type Id: VertexId;
25 type EdgeMeta: EdgeMetadata;
26}
27
28impl<M: VertexMetadata> Vertex<M>
29where
30 <M as VertexMetadata>::Id: VertexId,
31{
32 pub(crate) fn new(
33 id: M::Id,
34 parent: &inspect::Node,
35 init_metadata: impl FnOnce(inspect::Node) -> M,
36 ) -> Self {
37 parent.atomic_update(|parent| {
38 let id_str = id.get_id();
39 let node = parent.create_child(id_str.as_ref());
40 let outgoing_edges_node = node.create_child("relationships");
41 let metadata = init_metadata(node.create_child("meta"));
42 Vertex {
43 id,
44 _node: node,
45 outgoing_edges_node,
46 metadata,
47 incoming_edges: BTreeMap::new(),
48 outgoing_edges: BTreeMap::new(),
49 }
50 })
51 }
52
53 pub fn add_edge(
56 &mut self,
57 to: &mut Vertex<M>,
58 init_metadata: impl FnOnce(inspect::Node) -> M::EdgeMeta,
59 ) -> Edge<M::EdgeMeta> {
60 let edge = Edge::new(self, to, init_metadata);
61
62 let weak_ref = edge.weak_ref();
63 let edge_id = edge.id();
64
65 self.outgoing_edges.retain(|_, n| n.is_valid());
66 to.incoming_edges.retain(|_, n| n.is_valid());
67
68 to.incoming_edges.insert(edge_id, weak_ref.clone());
69 self.outgoing_edges.insert(edge_id, weak_ref);
70 edge
71 }
72
73 pub fn meta(&mut self) -> &mut M {
75 &mut self.metadata
76 }
77
78 pub(crate) fn id(&self) -> &M::Id {
79 &self.id
80 }
81}
82
83impl<M> Drop for Vertex<M>
84where
85 M: VertexMetadata,
86{
87 fn drop(&mut self) {
88 self.outgoing_edges.iter().for_each(|(_, n)| n.mark_as_gone());
89 self.incoming_edges.iter().for_each(|(_, n)| n.mark_as_gone());
90 }
91}