1use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
14#[serde(rename_all = "snake_case")]
15pub enum Language {
16 Python,
17 TypeScript,
18 JavaScript,
19 Go,
20 Rust,
21 Java,
22 Kotlin,
23 Ruby,
24 CSharp,
25 Cpp,
26 C,
27 Php,
28 Scala,
29 Swift,
30 Other(String),
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
35#[serde(rename_all = "snake_case")]
36pub enum SymbolKind {
37 File,
38 Module,
39 Namespace,
40 Class,
41 Interface,
42 Trait,
43 Enum,
44 Struct,
45 Function,
46 Method,
47 Field,
48 Variable,
49 Constant,
50 Import,
51 TypeAlias,
52 Process,
54 Contract,
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
60#[serde(rename_all = "snake_case")]
61pub enum EdgeKind {
62 Contains,
63 Imports,
64 Calls,
65 Instantiates,
66 Inherits,
67 Implements,
68 References,
69 Defines,
70 Uses,
71 ParticipatesIn,
72 Serves,
74 Consumes,
75 Publishes,
76 Subscribes,
77 Reads,
78 Writes,
79}
80
81impl EdgeKind {
82 pub fn as_str(&self) -> &'static str {
84 match self {
85 EdgeKind::Contains => "contains",
86 EdgeKind::Imports => "imports",
87 EdgeKind::Calls => "calls",
88 EdgeKind::Instantiates => "instantiates",
89 EdgeKind::Inherits => "inherits",
90 EdgeKind::Implements => "implements",
91 EdgeKind::References => "references",
92 EdgeKind::Defines => "defines",
93 EdgeKind::Uses => "uses",
94 EdgeKind::ParticipatesIn => "participates_in",
95 EdgeKind::Serves => "serves",
96 EdgeKind::Consumes => "consumes",
97 EdgeKind::Publishes => "publishes",
98 EdgeKind::Subscribes => "subscribes",
99 EdgeKind::Reads => "reads",
100 EdgeKind::Writes => "writes",
101 }
102 }
103}
104
105impl std::fmt::Display for EdgeKind {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 f.write_str(self.as_str())
108 }
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
113pub struct RepoId(pub String);
114
115#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
117pub struct Commit(pub String);
118
119#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
125pub struct GlobalSymbolId {
126 pub scheme: String,
128 pub package_manager: String,
130 pub package: String,
132 pub version: String,
134 pub descriptor: String,
136}
137
138impl GlobalSymbolId {
139 pub fn render(&self) -> String {
141 format!(
142 "{} {} {} {} {}",
143 self.scheme, self.package_manager, self.package, self.version, self.descriptor
144 )
145 }
146
147 pub fn is_package_managed(&self) -> bool {
150 self.package_manager != "."
151 }
152}
153
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
156pub struct Position {
157 pub line: u32,
158 pub column: u32,
159}
160
161#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
163pub struct Range {
164 pub start: Position,
165 pub end: Position,
166}
167
168#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
170pub struct Symbol {
171 pub id: GlobalSymbolId,
172 pub name: String,
173 pub kind: SymbolKind,
174 pub language: Language,
175 pub repo: RepoId,
176 pub file_path: String,
178 pub range: Range,
179 pub signature: Option<String>,
180 pub docstring: Option<String>,
181 #[serde(default)]
182 pub fingerprint: Option<Fingerprint>,
183}
184
185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
187pub struct Fingerprint {
188 pub sig: u64,
189 pub body: u64,
190 pub shape: u64,
191}
192
193#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
196pub struct Edge {
197 pub src: GlobalSymbolId,
198 pub dst: GlobalSymbolId,
199 pub kind: EdgeKind,
200 pub confidence: f32,
202 pub cross_repo: bool,
204}
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209
210 #[test]
211 fn scip_id_renders_and_detects_managed() {
212 let id = GlobalSymbolId {
213 scheme: "scip-python".into(),
214 package_manager: "pip".into(),
215 package: "acme".into(),
216 version: "1.4.0".into(),
217 descriptor: "acme/foo/bar().".into(),
218 };
219 assert_eq!(id.render(), "scip-python pip acme 1.4.0 acme/foo/bar().");
220 assert!(id.is_package_managed());
221
222 let local = GlobalSymbolId {
223 package_manager: ".".into(),
224 ..id
225 };
226 assert!(!local.is_package_managed());
227 }
228}