1use serde::{Deserialize, Serialize};
2
3use crate::schema;
4
5#[derive(Debug, Default, Serialize, Deserialize)]
12pub struct ProjectIr {
13 pub files: Vec<FileIr>,
14 pub modules: Vec<ModuleIr>,
15 pub functions: Vec<FunctionIr>,
16 pub api_endpoints: Vec<ApiEndpointIr>,
17 pub external_apis: Vec<ExternalApiIr>,
18 pub edges: Vec<EdgeIr>,
19 #[serde(default)]
21 pub classes: Vec<ClassIr>,
22 #[serde(default)]
24 pub properties: Vec<PropertyIr>,
25 #[serde(default)]
27 pub behaviours: Vec<BehaviourIr>,
28 #[serde(default)]
30 pub callbacks: Vec<CallbackIr>,
31}
32
33impl ProjectIr {
34 pub fn empty() -> Self {
35 Self::default()
36 }
37}
38
39#[derive(Debug, Serialize, Deserialize)]
41pub struct FileIr {
42 pub path: String,
43 pub language: String,
44 pub framework: Option<String>,
45 pub project_name: Option<String>,
46}
47
48#[derive(Debug, Serialize, Deserialize)]
50pub struct ModuleIr {
51 pub name: String,
52 pub path: String,
53 pub language: String,
54 pub framework: Option<String>,
55 pub project_name: Option<String>,
56 #[serde(default, skip_serializing_if = "Option::is_none")]
58 pub code_bytes: Option<Vec<u8>>,
59}
60
61#[derive(Debug, Serialize, Deserialize)]
63pub struct ClassIr {
64 pub fqn: String,
65 pub name: String,
66 pub path: String,
67 pub language: String,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub project_name: Option<String>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub kind: Option<String>,
72 #[serde(default, skip_serializing_if = "Option::is_none")]
73 pub code_bytes: Option<Vec<u8>>,
74}
75
76#[derive(Debug, Serialize, Deserialize)]
78pub struct PropertyIr {
79 pub fqn: String,
80 pub name: String,
81 pub class_fqn: String,
82 pub path: String,
83 pub language: String,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub project_name: Option<String>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub declared_type: Option<String>,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
89 pub code_bytes: Option<Vec<u8>>,
90}
91
92#[derive(Debug, Serialize, Deserialize)]
94pub struct FunctionIr {
95 pub name: String,
96 pub fqn: String,
97 pub path: String,
98 pub language: String,
99 pub framework: Option<String>,
100 pub project_name: Option<String>,
101 pub arity: Option<u32>,
102 pub return_type: Option<String>,
103 pub param_count: Option<u32>,
104 pub param_types: Vec<String>,
105 #[serde(default, skip_serializing_if = "Option::is_none")]
106 pub code_bytes: Option<Vec<u8>>,
107}
108
109#[derive(Debug, Serialize, Deserialize)]
111pub struct ApiEndpointIr {
112 pub methods: Vec<String>,
113 pub path: String,
114 pub protocol: Option<String>,
115 pub framework: Option<String>,
116 pub project_name: Option<String>,
117}
118
119#[derive(Debug, Serialize, Deserialize)]
121pub struct ExternalApiIr {
122 pub name: String,
123 pub base_url: Option<String>,
124 pub protocol: Option<String>,
125 pub provider: Option<String>,
126 pub service: Option<String>,
127 #[serde(skip_serializing_if = "Option::is_none")]
128 pub norm_path: Option<String>,
129}
130
131#[derive(Debug, Serialize, Deserialize)]
133pub struct BehaviourIr {
134 pub name: String,
135 #[serde(skip_serializing_if = "Option::is_none")]
136 pub path: Option<String>,
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub language: Option<String>,
139 #[serde(skip_serializing_if = "Option::is_none")]
140 pub project_name: Option<String>,
141}
142
143#[derive(Debug, Serialize, Deserialize)]
145pub struct CallbackIr {
146 pub name: String,
147 pub fqn: String,
148 pub arity: u32,
149 pub optional: bool,
150 #[serde(skip_serializing_if = "Option::is_none")]
151 pub language: Option<String>,
152 #[serde(skip_serializing_if = "Option::is_none")]
153 pub project_name: Option<String>,
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
158pub enum EdgeKind {
159 DeclaresModule,
160 DeclaresFunction,
161 DeclaresClass,
162 DeclaresProperty,
163 DependsOnFile,
164 CallsFunction,
165 HandlesApi,
166 CallsExternalApi,
167 UsesClass,
169 ClassUsesClass,
171 SameApi,
172 ImplementsBehaviour,
173 DeclaresCallback,
174 ImplementsCallback,
175 DeclaresBehaviour,
176 ExtendsBehaviour,
177 OverridesCallback,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct EdgeIr {
194 pub kind: EdgeKind,
195 pub from_label: String,
197 pub from_key: String,
199 pub to_label: String,
201 pub to_key: String,
203}
204
205impl EdgeKind {
206 pub fn to_rel_type(&self) -> crate::edge::RelType {
210 use crate::edge::RelType;
211 match self {
212 EdgeKind::DeclaresModule => RelType::DeclaresModule,
213 EdgeKind::DeclaresFunction => RelType::DeclaresFunction,
214 EdgeKind::DeclaresClass => RelType::DeclaresClass,
215 EdgeKind::DeclaresProperty => RelType::DeclaresProperty,
216 EdgeKind::DependsOnFile => RelType::DependsOnFile,
217 EdgeKind::CallsFunction => RelType::CallsFunction,
218 EdgeKind::HandlesApi => RelType::HandlesApi,
219 EdgeKind::CallsExternalApi => RelType::CallsExternalApi,
220 EdgeKind::UsesClass => RelType::UsesClass,
221 EdgeKind::ClassUsesClass => RelType::ClassUsesClass,
222 EdgeKind::SameApi => RelType::SameApi,
223 EdgeKind::ImplementsBehaviour => RelType::ImplementsBehaviour,
224 EdgeKind::DeclaresCallback => RelType::DeclaresCallback,
225 EdgeKind::ImplementsCallback => RelType::ImplementsCallback,
226 EdgeKind::DeclaresBehaviour => RelType::DeclaresBehaviour,
227 EdgeKind::ExtendsBehaviour => RelType::ExtendsBehaviour,
228 EdgeKind::OverridesCallback => RelType::OverridesCallback,
229 }
230 }
231}
232
233pub fn external_api_key(base_url: &str, norm_path: &str) -> String {
235 format!("{base_url}|{norm_path}")
236}
237
238pub fn api_endpoint_key(methods: &[String], path: &str) -> String {
240 format!("{} {}", methods.join(","), path)
241}
242
243pub fn module_key(name: &str, path: &str) -> String {
245 format!("{name}@{path}")
246}
247
248impl From<schema::NodeLabel> for String {
249 fn from(label: schema::NodeLabel) -> Self {
250 label.to_string()
251 }
252}
253
254