Skip to main content

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