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(name: impl Into<String>, parameters: Vec<Field>, returns: Vec<Field>, body: impl Into<String>) -> Self {
33        let name = name.into();
34        Self {
35            name: name.clone(),
36            parameters: sort_parameters(parameters),
37            return_row_type: Type::struct_(format!("{}RespRow", name.to_case(Case::Pascal)), returns),
38            body: body.into(),
39        }
40    }
41
42    /// Creates a new `ProceduralFunction` with the given name, parameters, row type and body.
43    pub fn new_with_row_type(
44        name: impl Into<String>,
45        parameters: Vec<Field>,
46        return_row_type: Type,
47        body: impl Into<String>,
48    ) -> Self {
49        Self {
50            name: name.into(),
51            parameters: sort_parameters(parameters),
52            return_row_type,
53            body: body.into(),
54        }
55    }
56}