1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7#[repr(u8)]
8pub enum EdgeType {
9 Calls = 0,
11 Imports = 1,
13 Inherits = 2,
15 Implements = 3,
17 Overrides = 4,
19 Contains = 5,
21 References = 6,
23 Tests = 7,
25 Documents = 8,
27 Configures = 9,
29 CouplesWith = 10,
31 BreaksWith = 11,
33 PatternOf = 12,
35 VersionOf = 13,
37 FfiBinds = 14,
39 UsesType = 15,
41 Returns = 16,
43 ParamType = 17,
45}
46
47impl EdgeType {
48 pub fn from_u8(value: u8) -> Option<Self> {
52 match value {
53 0 => Some(Self::Calls),
54 1 => Some(Self::Imports),
55 2 => Some(Self::Inherits),
56 3 => Some(Self::Implements),
57 4 => Some(Self::Overrides),
58 5 => Some(Self::Contains),
59 6 => Some(Self::References),
60 7 => Some(Self::Tests),
61 8 => Some(Self::Documents),
62 9 => Some(Self::Configures),
63 10 => Some(Self::CouplesWith),
64 11 => Some(Self::BreaksWith),
65 12 => Some(Self::PatternOf),
66 13 => Some(Self::VersionOf),
67 14 => Some(Self::FfiBinds),
68 15 => Some(Self::UsesType),
69 16 => Some(Self::Returns),
70 17 => Some(Self::ParamType),
71 _ => None,
72 }
73 }
74
75 pub fn is_dependency(&self) -> bool {
77 matches!(
78 self,
79 Self::Calls
80 | Self::Imports
81 | Self::Inherits
82 | Self::Implements
83 | Self::UsesType
84 | Self::FfiBinds
85 )
86 }
87
88 pub fn is_temporal(&self) -> bool {
90 matches!(self, Self::CouplesWith | Self::BreaksWith | Self::VersionOf)
91 }
92
93 pub fn label(&self) -> &'static str {
95 match self {
96 Self::Calls => "calls",
97 Self::Imports => "imports",
98 Self::Inherits => "inherits",
99 Self::Implements => "implements",
100 Self::Overrides => "overrides",
101 Self::Contains => "contains",
102 Self::References => "references",
103 Self::Tests => "tests",
104 Self::Documents => "documents",
105 Self::Configures => "configures",
106 Self::CouplesWith => "couples_with",
107 Self::BreaksWith => "breaks_with",
108 Self::PatternOf => "pattern_of",
109 Self::VersionOf => "version_of",
110 Self::FfiBinds => "ffi_binds",
111 Self::UsesType => "uses_type",
112 Self::Returns => "returns",
113 Self::ParamType => "param_type",
114 }
115 }
116
117 pub const COUNT: usize = 18;
119}
120
121impl std::fmt::Display for EdgeType {
122 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 write!(f, "{}", self.label())
124 }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
129pub struct Edge {
130 pub source_id: u64,
132
133 pub target_id: u64,
135
136 pub edge_type: EdgeType,
138
139 pub weight: f32,
142
143 pub created_at: u64,
145
146 pub context: u32,
148}
149
150impl Edge {
151 pub fn new(source_id: u64, target_id: u64, edge_type: EdgeType) -> Self {
153 Self {
154 source_id,
155 target_id,
156 edge_type,
157 weight: 1.0,
158 created_at: crate::types::now_micros(),
159 context: 0,
160 }
161 }
162
163 pub fn with_weight(mut self, weight: f32) -> Self {
165 self.weight = weight.clamp(0.0, 1.0);
166 self
167 }
168
169 pub fn with_context(mut self, context: u32) -> Self {
171 self.context = context;
172 self
173 }
174
175 pub fn is_self_edge(&self) -> bool {
177 self.source_id == self.target_id
178 }
179}