1use serde::{Deserialize, Serialize};
2use crate::model::{VariableId, FunctionId, ScopeId};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct OwnershipGraph {
6 pub nodes: Vec<GraphNode>,
7 pub edges: Vec<GraphEdge>,
8}
9
10impl OwnershipGraph {
11 pub fn new() -> Self {
12 Self {
13 nodes: Vec::new(),
14 edges: Vec::new(),
15 }
16 }
17
18 pub fn add_node(&mut self, node: GraphNode) {
19 if !self.nodes.contains(&node) {
20 self.nodes.push(node);
21 }
22 }
23
24 pub fn add_edge(&mut self, edge: GraphEdge) {
25 self.edges.push(edge);
26 }
27
28 pub fn get_edges_for_variable(&self, var_id: VariableId) -> Vec<&GraphEdge> {
29 self.edges.iter()
30 .filter(|e| {
31 matches!(&e.source, GraphNode::Variable(id) if *id == var_id) ||
32 matches!(&e.target, GraphNode::Variable(id) if *id == var_id)
33 })
34 .collect()
35 }
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39pub enum GraphNode {
40 Variable(VariableId),
41 Reference(VariableId),
42 Function(FunctionId),
43 Scope(ScopeId),
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct GraphEdge {
48 pub source: GraphNode,
49 pub target: GraphNode,
50 pub kind: EdgeKind,
51 pub label: Option<String>,
52}
53
54impl GraphEdge {
55 pub fn new(source: GraphNode, target: GraphNode, kind: EdgeKind) -> Self {
56 Self {
57 source,
58 target,
59 kind,
60 label: None,
61 }
62 }
63
64 pub fn with_label(mut self, label: String) -> Self {
65 self.label = Some(label);
66 self
67 }
68}
69
70#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
71pub enum EdgeKind {
72 Owns,
73 Borrows,
74 MutablyBorrows,
75 MovesTo,
76 Reborrows,
77 DropsAt,
78 LivesInScope,
79}