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 = "js")]
202 Js,
203 #[serde(rename = "ts")]
205 Ts,
206 #[serde(rename = "go")]
210 Go,
211 }
217
218impl FunctionToolchain {
219 #[must_use]
220 pub fn as_str(&self) -> &'static str {
221 match self {
222 Self::Rs => "rust",
223 Self::Js => "js",
224 Self::Ts => "ts",
225 Self::Go => "go",
226 }
227 }
228}
229
230#[cfg(feature = "cli")]
231impl std::fmt::Display for FunctionToolchain {
232 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
233 match self {
234 Self::Rs => write!(f, "rust"),
235 Self::Js => write!(f, "js"),
236 Self::Ts => write!(f, "ts"),
237 Self::Go => write!(f, "go"),
238 }
239 }
240}
241
242#[cfg(feature = "cli")]
243impl clap::ValueEnum for FunctionToolchain {
244 fn value_variants<'a>() -> &'a [Self] {
245 &[Self::Rs, Self::Go, Self::Js, Self::Ts]
246 }
247
248 fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
249 match self {
250 Self::Rs => Some(clap::builder::PossibleValue::new("rust")),
251 Self::Js => Some(clap::builder::PossibleValue::new("js")),
252 Self::Ts => Some(clap::builder::PossibleValue::new("ts")),
253 Self::Go => Some(clap::builder::PossibleValue::new("go")),
254 }
255 }
256}
257
258#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
260#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
261#[derive(Deserialize, Serialize, Debug, Clone, PartialOrd, PartialEq, Eq, Hash)]
262pub enum FunctionAccessDatabaseOps {
263 Insert,
265 Get,
267 Query,
269 Update,
271 Delete,
273}
274
275#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
277#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
278#[derive(Deserialize, Serialize, Debug, Clone)]
279pub enum FunctionAccessAuthOps {
280 SetClaims,
283}
284
285#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
288#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
289#[derive(Deserialize, Serialize, Debug, Clone)]
290pub enum FunctionAccessPermission {
291 DatabaseModel {
293 name: String,
295 ops: Vec<FunctionAccessDatabaseOps>,
298 },
299 Auth {
301 ops: Vec<FunctionAccessAuthOps>,
303 },
304}