Skip to main content

reifydb_core/interface/catalog/
procedure.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::path::PathBuf;
5
6use reifydb_type::value::{constraint::TypeConstraint, sumtype::VariantRef};
7use serde::{Deserialize, Serialize};
8
9use crate::interface::catalog::id::{NamespaceId, ProcedureId};
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
12pub enum RqlTrigger {
13	#[default]
14	Call,
15
16	Event {
17		variant: VariantRef,
18	},
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
22pub enum ProcedureKind {
23	Rql,
24	Test,
25	Native,
26	Ffi,
27	Wasm,
28}
29
30impl ProcedureKind {
31	pub fn as_str(&self) -> &'static str {
32		match self {
33			ProcedureKind::Rql => "rql",
34			ProcedureKind::Test => "test",
35			ProcedureKind::Native => "native",
36			ProcedureKind::Ffi => "ffi",
37			ProcedureKind::Wasm => "wasm",
38		}
39	}
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
43#[repr(transparent)]
44pub struct WasmModuleId(pub u64);
45
46#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
47pub struct ProcedureParam {
48	pub name: String,
49	pub param_type: TypeConstraint,
50}
51
52#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53pub enum Procedure {
54	Rql {
55		id: ProcedureId,
56		namespace: NamespaceId,
57		name: String,
58		params: Vec<ProcedureParam>,
59		return_type: Option<TypeConstraint>,
60		body: String,
61		trigger: RqlTrigger,
62	},
63
64	Test {
65		id: ProcedureId,
66		namespace: NamespaceId,
67		name: String,
68		params: Vec<ProcedureParam>,
69		return_type: Option<TypeConstraint>,
70		body: String,
71	},
72
73	Native {
74		id: ProcedureId,
75		namespace: NamespaceId,
76		name: String,
77		params: Vec<ProcedureParam>,
78		return_type: Option<TypeConstraint>,
79		native_name: String,
80	},
81
82	Ffi {
83		id: ProcedureId,
84		namespace: NamespaceId,
85		name: String,
86		params: Vec<ProcedureParam>,
87		return_type: Option<TypeConstraint>,
88		native_name: String,
89		library_path: PathBuf,
90		entry_symbol: String,
91	},
92
93	Wasm {
94		id: ProcedureId,
95		namespace: NamespaceId,
96		name: String,
97		params: Vec<ProcedureParam>,
98		return_type: Option<TypeConstraint>,
99		native_name: String,
100		module_id: WasmModuleId,
101	},
102}
103
104impl Procedure {
105	pub fn id(&self) -> ProcedureId {
106		match self {
107			Procedure::Rql {
108				id,
109				..
110			}
111			| Procedure::Test {
112				id,
113				..
114			}
115			| Procedure::Native {
116				id,
117				..
118			}
119			| Procedure::Ffi {
120				id,
121				..
122			}
123			| Procedure::Wasm {
124				id,
125				..
126			} => *id,
127		}
128	}
129
130	pub fn namespace(&self) -> NamespaceId {
131		match self {
132			Procedure::Rql {
133				namespace,
134				..
135			}
136			| Procedure::Test {
137				namespace,
138				..
139			}
140			| Procedure::Native {
141				namespace,
142				..
143			}
144			| Procedure::Ffi {
145				namespace,
146				..
147			}
148			| Procedure::Wasm {
149				namespace,
150				..
151			} => *namespace,
152		}
153	}
154
155	pub fn name(&self) -> &str {
156		match self {
157			Procedure::Rql {
158				name,
159				..
160			}
161			| Procedure::Test {
162				name,
163				..
164			}
165			| Procedure::Native {
166				name,
167				..
168			}
169			| Procedure::Ffi {
170				name,
171				..
172			}
173			| Procedure::Wasm {
174				name,
175				..
176			} => name.as_str(),
177		}
178	}
179
180	pub fn params(&self) -> &[ProcedureParam] {
181		match self {
182			Procedure::Rql {
183				params,
184				..
185			}
186			| Procedure::Test {
187				params,
188				..
189			}
190			| Procedure::Native {
191				params,
192				..
193			}
194			| Procedure::Ffi {
195				params,
196				..
197			}
198			| Procedure::Wasm {
199				params,
200				..
201			} => params,
202		}
203	}
204
205	pub fn return_type(&self) -> Option<&TypeConstraint> {
206		match self {
207			Procedure::Rql {
208				return_type,
209				..
210			}
211			| Procedure::Test {
212				return_type,
213				..
214			}
215			| Procedure::Native {
216				return_type,
217				..
218			}
219			| Procedure::Ffi {
220				return_type,
221				..
222			}
223			| Procedure::Wasm {
224				return_type,
225				..
226			} => return_type.as_ref(),
227		}
228	}
229
230	pub fn kind(&self) -> ProcedureKind {
231		match self {
232			Procedure::Rql {
233				..
234			} => ProcedureKind::Rql,
235			Procedure::Test {
236				..
237			} => ProcedureKind::Test,
238			Procedure::Native {
239				..
240			} => ProcedureKind::Native,
241			Procedure::Ffi {
242				..
243			} => ProcedureKind::Ffi,
244			Procedure::Wasm {
245				..
246			} => ProcedureKind::Wasm,
247		}
248	}
249
250	pub fn is_persistent(&self) -> bool {
251		matches!(self, Procedure::Rql { .. } | Procedure::Test { .. })
252	}
253
254	pub fn event_variant(&self) -> Option<VariantRef> {
255		match self {
256			Procedure::Rql {
257				trigger: RqlTrigger::Event {
258					variant,
259				},
260				..
261			} => Some(*variant),
262			_ => None,
263		}
264	}
265
266	pub fn native_name(&self) -> Option<&str> {
267		match self {
268			Procedure::Native {
269				native_name,
270				..
271			}
272			| Procedure::Ffi {
273				native_name,
274				..
275			}
276			| Procedure::Wasm {
277				native_name,
278				..
279			} => Some(native_name.as_str()),
280			_ => None,
281		}
282	}
283
284	pub fn body(&self) -> Option<&str> {
285		match self {
286			Procedure::Rql {
287				body,
288				..
289			}
290			| Procedure::Test {
291				body,
292				..
293			} => Some(body.as_str()),
294			_ => None,
295		}
296	}
297}