impactsense_parser/schema.rs
1use std::fmt;
2
3/// Labels used for nodes in the Neo4j graph.
4///
5/// This file is the central "schema contract" describing what node types
6/// exist and which common properties they are expected to have.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum NodeLabel {
9 /// Source file (any language).
10 File,
11 /// Logical module / grouping of functions.
12 /// For Erlang this is one `.erl` file with a `-module(Name).`.
13 Module,
14 /// A concrete function or method.
15 Function,
16 /// OTP/custom behaviour contract node.
17 Behaviour,
18 /// Callback contract declared by a behaviour.
19 Callback,
20 /// An HTTP or RPC API endpoint exposed by the system.
21 ApiEndpoint,
22 /// An external API or service that the system calls out to.
23 ExternalApi,
24}
25
26impl fmt::Display for NodeLabel {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 let s = match self {
29 NodeLabel::File => "File",
30 NodeLabel::Module => "Module",
31 NodeLabel::Function => "Function",
32 NodeLabel::Behaviour => "Behaviour",
33 NodeLabel::Callback => "Callback",
34 NodeLabel::ApiEndpoint => "ApiEndpoint",
35 NodeLabel::ExternalApi => "ExternalApi",
36 };
37 f.write_str(s)
38 }
39}
40
41/// Common property keys shared across node types.
42pub mod props {
43 /// Filesystem or project‑relative path.
44 pub const PATH: &str = "path";
45 /// Programming language of the artifact (e.g. "erlang", "java").
46 pub const LANGUAGE: &str = "language";
47 /// Web / application framework (e.g. "cowboy", "spring").
48 pub const FRAMEWORK: &str = "framework";
49 /// Logical project or service name (e.g. "omega").
50 pub const PROJECT_NAME: &str = "project_name";
51 /// Simple name (module name, function name, etc.).
52 pub const NAME: &str = "name";
53 /// Fully-qualified name for symbols (e.g. module:function/arity or
54 /// com.example.Class.method).
55 pub const FQN: &str = "fqn";
56 /// Arity for languages that care about it (e.g. Erlang).
57 pub const ARITY: &str = "arity";
58 /// Return type of the function when it is explicitly declared (Java, C#,
59 /// Go, Erlang -spec, etc.). This is optional and may be absent for
60 /// dynamically-typed or unannotated code.
61 pub const RETURN_TYPE: &str = "return_type";
62 /// Number of parameters the function takes. For Erlang this should match
63 /// `arity`; for other languages it is simply the parameter list length.
64 pub const PARAM_COUNT: &str = "param_count";
65 /// Parameter types when they are explicitly written in the source (e.g.
66 /// Java, C#, Go, TypeScript). Stored as an array of strings.
67 pub const PARAM_TYPES: &str = "param_types";
68 /// Whether callback is optional for its behaviour contract.
69 pub const OPTIONAL: &str = "optional";
70 /// HTTP method(s) for an API endpoint, e.g. GET/POST.
71 pub const METHOD: &str = "method";
72 /// Canonical path for an API endpoint, e.g. "/omega/api/getavroutes".
73 pub const PATH_TEMPLATE: &str = "path";
74 /// Protocol for the endpoint (e.g. "http", "https", "grpc").
75 pub const PROTOCOL: &str = "protocol";
76 /// Base URL for an external API, e.g. "https://api.vendorx.com".
77 pub const BASE_URL: &str = "base_url";
78 /// Logical provider/vendor name for an external API, e.g. "VendorX".
79 pub const PROVIDER: &str = "provider";
80 /// Logical service domain for an external API, e.g. "payments",
81 /// "inventory", "search".
82 pub const SERVICE: &str = "service";
83 /// Zstd-compressed source snippet (RedCompressor wire format, raw bytes).
84 pub const CODE_BYTES: &str = "code_bytes";
85}
86
87/// Structured view of the properties we expect on a `File` node.
88#[derive(Debug, Clone)]
89pub struct FileNode<'a> {
90 pub path: &'a str,
91 pub language: &'a str,
92 pub framework: Option<&'a str>,
93 pub project_name: Option<&'a str>,
94}
95
96/// Structured view of the properties we expect on a `Module` node.
97#[derive(Debug, Clone)]
98pub struct ModuleNode<'a> {
99 pub name: &'a str,
100 pub path: &'a str,
101 pub language: &'a str,
102 pub framework: Option<&'a str>,
103 pub project_name: Option<&'a str>,
104}
105
106/// Structured view of the properties we expect on a `Function` node.
107///
108/// This is intentionally generic and works across languages:
109/// - Erlang: `name`, `arity`, `fqn = "module:name/arity"`.
110/// - Java / C#: `name`, `arity = None`, `fqn` includes class + method.
111#[derive(Debug, Clone)]
112pub struct FunctionNode<'a> {
113 pub name: &'a str,
114 pub fqn: &'a str,
115 pub path: &'a str,
116 pub language: &'a str,
117 pub framework: Option<&'a str>,
118 pub project_name: Option<&'a str>,
119 /// For Erlang this should be `Some(arity)`, for many other languages it
120 /// can remain `None`.
121 pub arity: Option<u32>,
122 /// Explicit return type, if it can be extracted from the syntax tree or
123 /// type annotations.
124 pub return_type: Option<&'a str>,
125 /// Number of parameters, if it can be extracted. For parameter-less
126 /// functions this is typically `Some(0)`, but callers may also choose to
127 /// leave it as `None` if they do not compute it.
128 pub param_count: Option<u32>,
129 /// Parameter type names in declaration order, when available. This allows
130 /// richer queries like "which functions take an OrderDetail as input?".
131 pub param_types: Option<&'a [&'a str]>,
132}
133
134/// Structured view of the properties we expect on a `Behaviour` node.
135#[derive(Debug, Clone)]
136pub struct BehaviourNode<'a> {
137 /// Behaviour name, e.g. `gen_server`, `my_custom_behaviour`.
138 pub name: &'a str,
139 /// File path where this behaviour is declared (if local/custom).
140 pub path: Option<&'a str>,
141 pub language: Option<&'a str>,
142 pub project_name: Option<&'a str>,
143}
144
145/// Structured view of the properties we expect on a `Callback` node.
146#[derive(Debug, Clone)]
147pub struct CallbackNode<'a> {
148 /// Callback simple name, e.g. `handle_call`.
149 pub name: &'a str,
150 /// Stable callback key, e.g. `gen_server:handle_call/3`.
151 pub fqn: &'a str,
152 pub arity: u32,
153 pub optional: bool,
154 pub language: Option<&'a str>,
155 pub project_name: Option<&'a str>,
156}
157
158/// Structured view of the properties we expect on an `ApiEndpoint` node.
159///
160/// This shape is intentionally minimal and framework-agnostic so it can be
161/// populated from Erlang/Cowboy, Java/Spring, JS/Express, etc.
162#[derive(Debug, Clone)]
163pub struct ApiEndpointNode<'a> {
164 /// HTTP methods for this endpoint (e.g. ["GET"], ["GET","POST"]).
165 pub methods: &'a [&'a str],
166 /// Canonical path template, e.g. "/omega/api/getavroutes" or
167 /// "/orders/{id}".
168 pub path: &'a str,
169 /// Protocol such as "http" or "https".
170 pub protocol: Option<&'a str>,
171 /// Framework that exposes this endpoint (e.g. "cowboy", "spring").
172 pub framework: Option<&'a str>,
173 /// Logical project/service name this endpoint belongs to.
174 pub project_name: Option<&'a str>,
175}
176
177/// Structured view of the properties we expect on an `ExternalApi` node.
178///
179/// This represents a remote system or API surface that our code calls into.
180/// Multiple internal functions across projects/frameworks can all point to
181/// the same `ExternalApi` node via `CALLS_EXTERNAL_API` edges.
182#[derive(Debug, Clone)]
183pub struct ExternalApiNode<'a> {
184 /// Human-friendly logical name, e.g. "VendorX", "Stripe", "GDS-Search".
185 pub name: &'a str,
186 /// Base URL if it is an HTTP(S) API, e.g. "https://api.vendorx.com".
187 pub base_url: Option<&'a str>,
188 /// Protocol such as "http", "https", "grpc", "kafka".
189 pub protocol: Option<&'a str>,
190 /// Provider or organization behind the API, e.g. "VendorX".
191 pub provider: Option<&'a str>,
192 /// Logical service domain, e.g. "payments", "inventory", "search".
193 pub service: Option<&'a str>,
194}
195
196