Skip to main content

endpoint_libs/model/
pg_func.rs

1use crate::model::{Field, Type};
2use convert_case::Case;
3use convert_case::Casing;
4use itertools::Itertools;
5
6/// `ProceduralFunction` is a struct that represents a single procedural function in the API.
7#[derive(Clone, Debug)]
8pub struct ProceduralFunction {
9    /// The name of the function (e.g. `fun_user_get_user`)
10    pub name: String,
11
12    /// A list of parameters that the function accepts (e.g. "user_id" of type `Type::BigInt`)
13    pub parameters: Vec<Field>,
14
15    /// The return type of the function (e.g. `Type::struct_`)
16    pub return_row_type: Type,
17
18    /// The actual SQL body of the function (e.g. `SELECT * FROM user WHERE user_id = $1`)
19    pub body: String,
20}
21
22/// Sorts the parameters by the type, so that optional parameters are last.
23fn sort_parameters(parameters: Vec<Field>) -> Vec<Field> {
24    parameters
25        .into_iter()
26        .sorted_by_cached_key(|x| matches!(x.ty, Type::Optional(_)))
27        .collect()
28}
29
30impl ProceduralFunction {
31    /// Creates a new `ProceduralFunction` with the given name, parameters, returns and body.
32    pub fn new(
33        name: impl Into<String>,
34        parameters: Vec<Field>,
35        returns: Vec<Field>,
36        body: impl Into<String>,
37    ) -> Self {
38        let name = name.into();
39        Self {
40            name: name.clone(),
41            parameters: sort_parameters(parameters),
42            return_row_type: Type::struct_(
43                format!("{}RespRow", name.to_case(Case::Pascal)),
44                returns,
45            ),
46            body: body.into(),
47        }
48    }
49
50    /// Creates a new `ProceduralFunction` with the given name, parameters, row type and body.
51    pub fn new_with_row_type(
52        name: impl Into<String>,
53        parameters: Vec<Field>,
54        return_row_type: Type,
55        body: impl Into<String>,
56    ) -> Self {
57        Self {
58            name: name.into(),
59            parameters: sort_parameters(parameters),
60            return_row_type,
61            body: body.into(),
62        }
63    }
64}