ordinary_config/app/function/
mod.rs1use crate::{Bindgen, StoredCache};
6use ordinary_types::Kind;
7use serde::{Deserialize, Serialize};
8
9#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
11#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
12#[derive(Deserialize, Serialize, Debug, Clone, Default)]
13pub struct FunctionConfig {
14 #[serde(skip_serializing_if = "Option::is_none")]
16 #[serde(default)]
17 pub ffi: Option<FunctionFfi>,
18 #[serde(skip_serializing_if = "Option::is_none")]
20 #[serde(default, rename = "ref")]
21 pub r#ref: Option<String>,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
25 #[serde(default)]
26 pub name: Option<String>,
27
28 #[serde(skip_serializing_if = "Option::is_none")]
29 #[serde(default)]
30 pub readonly: Option<bool>,
31
32 #[serde(skip_serializing_if = "Option::is_none")]
49 #[serde(default)]
50 pub bindgen: Option<Bindgen>,
51 #[serde(skip_serializing_if = "Option::is_none")]
53 #[serde(default)]
54 pub toolchain: Option<FunctionToolchain>,
55 #[serde(skip_serializing_if = "Option::is_none")]
58 #[serde(default)]
59 pub build: Option<Vec<Vec<String>>>,
60 #[serde(skip_serializing_if = "Option::is_none")]
62 #[serde(default)]
63 pub bin: Option<String>,
64
65 #[serde(skip_serializing_if = "Option::is_none")]
68 #[serde(default)]
69 pub protected: Option<bool>,
70 #[serde(skip_serializing_if = "Option::is_none")]
73 #[serde(default)]
74 pub access: Option<Vec<FunctionAccessPermission>>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
78 #[serde(default)]
79 pub input: Option<Kind>,
80 #[serde(skip_serializing_if = "Option::is_none")]
82 #[serde(default)]
83 pub output: Option<Kind>,
84
85 #[serde(skip_serializing_if = "Option::is_none")]
88 #[serde(default)]
89 pub cache: Option<StoredCache>,
90
91 #[serde(skip_serializing_if = "Option::is_none")]
95 #[serde(default)]
96 pub variables: Option<Vec<String>>,
97
98 #[serde(skip_serializing_if = "Option::is_none")]
102 #[serde(default)]
103 pub timeout: Option<u16>,
104}
105
106impl FunctionConfig {
107 #[allow(clippy::single_match)]
108 pub fn load_bindgen(&mut self) {
109 let function_name = self.name_validated().to_owned();
110
111 match self.bindgen {
112 Some(Bindgen::V1Rust) => {
113 self.ffi = Some(FunctionFfi {
114 version: FunctionFfiVersion::V1,
115 serialization: FunctionFfiSerialization::FlexBufferVector,
116 });
117
118 let mut build = self.build.clone().unwrap_or_default();
119 build.push(vec![
120 "sh".into(),
121 format!(".ordinary/{function_name}/build.sh"),
122 ]);
123 self.build = Some(build);
124 self.bin = Some(format!(".ordinary/{function_name}/function.wasm"));
125 }
126 _ => (),
127 }
128 }
129
130 #[must_use]
134 pub fn ffi_validated(&self) -> &FunctionFfi {
135 self.ffi.as_ref().expect("FFI should be present")
136 }
137
138 #[must_use]
142 pub fn name_validated(&self) -> &str {
143 self.name.as_deref().expect("Name should be present")
144 }
145
146 #[must_use]
150 pub fn input_validated(&self) -> &Kind {
151 self.input.as_ref().expect("Input should be present")
152 }
153
154 #[must_use]
158 pub fn output_validated(&self) -> &Kind {
159 self.output.as_ref().expect("Output should be present")
160 }
161}
162
163#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
164#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
165#[derive(Deserialize, Serialize, Debug, Clone, Default)]
166pub enum FunctionFfiVersion {
167 #[default]
168 V1,
169}
170
171#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
173#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
174#[derive(Deserialize, Serialize, Debug, Clone, Default)]
175pub enum FunctionFfiSerialization {
176 #[default]
177 FlexBufferVector,
178 Json,
179}
180
181#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
182#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
183#[derive(Deserialize, Serialize, Debug, Clone, Default)]
184pub struct FunctionFfi {
185 pub version: FunctionFfiVersion,
186 pub serialization: FunctionFfiSerialization,
187}
188
189#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
191#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
192#[derive(Deserialize, Serialize, Debug, Clone, Default)]
193pub enum FunctionToolchain {
194 #[default]
198 #[serde(rename = "rust")]
199 Rs,
200 #[serde(rename = "c")]
202 C,
203 #[serde(rename = "js")]
205 Js,
206 #[serde(rename = "ts")]
208 Ts,
209 #[serde(rename = "go")]
213 Go,
214 }
220
221impl FunctionToolchain {
222 #[must_use]
223 pub fn as_str(&self) -> &'static str {
224 match self {
225 Self::Rs => "rust",
226 Self::C => "c",
227 Self::Js => "js",
228 Self::Ts => "ts",
229 Self::Go => "go",
230 }
231 }
232}
233
234#[cfg(feature = "cli")]
235impl std::fmt::Display for FunctionToolchain {
236 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237 match self {
238 Self::Rs => write!(f, "rust"),
239 Self::C => write!(f, "c"),
240 Self::Js => write!(f, "js"),
241 Self::Ts => write!(f, "ts"),
242 Self::Go => write!(f, "go"),
243 }
244 }
245}
246
247#[cfg(feature = "cli")]
248impl clap::ValueEnum for FunctionToolchain {
249 fn value_variants<'a>() -> &'a [Self] {
250 &[Self::Rs, Self::C, Self::Go, Self::Js, Self::Ts]
251 }
252
253 fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
254 match self {
255 Self::Rs => Some(clap::builder::PossibleValue::new("rust")),
256 Self::C => Some(clap::builder::PossibleValue::new("c")),
257 Self::Js => Some(clap::builder::PossibleValue::new("js")),
258 Self::Ts => Some(clap::builder::PossibleValue::new("ts")),
259 Self::Go => Some(clap::builder::PossibleValue::new("go")),
260 }
261 }
262}
263
264#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
266#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
267#[derive(Deserialize, Serialize, Debug, Clone, PartialOrd, PartialEq, Eq, Hash)]
268pub enum FunctionAccessDatabaseOps {
269 Insert,
271 Get,
273 Query,
275 Update,
277 Delete,
279}
280
281#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
283#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
284#[derive(Deserialize, Serialize, Debug, Clone)]
285pub enum FunctionAccessAuthOps {
286 SetClaims,
289}
290
291#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
294#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
295#[derive(Deserialize, Serialize, Debug, Clone)]
296pub enum FunctionAccessPermission {
297 Database {
299 model: String,
301 ops: Vec<FunctionAccessDatabaseOps>,
304 },
305 Auth {
307 ops: Vec<FunctionAccessAuthOps>,
309 },
310 Extension {
313 name: String,
315 ops: Vec<String>,
317 },
318}