surrealdb_sql/
function.rs1use common::fmt::{EscapeIdent, EscapeKwFreeIdent, Fmt};
2use surrealdb_types::{SqlFormat, ToSql, write_sql};
3
4use crate::{CoverStmts, Expr, Idiom, Model, Script};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub enum Function {
8 Normal(String),
9 Custom(String),
10 Script(Script),
11 Model(Model),
12 Module(String, Option<String>),
13 Silo {
14 org: String,
15 pkg: String,
16 major: u32,
17 minor: u32,
18 patch: u32,
19 sub: Option<String>,
20 },
21}
22
23impl Function {
24 #[allow(clippy::inherent_to_string)]
26 pub fn to_string(&self) -> String {
27 match self {
28 Self::Script(_) => "function".to_owned(),
30 Self::Normal(f) => f.to_owned(),
31 Self::Custom(name) => format!("fn::{name}"),
32 Self::Model(m) => m.to_sql(),
33 Self::Module(m, s) => match s {
34 Some(s) => format!("mod::{m}::{s}"),
35 None => format!("mod::{m}"),
36 },
37 Self::Silo {
38 org,
39 pkg,
40 major,
41 minor,
42 patch,
43 sub,
44 } => match sub {
45 Some(s) => {
46 format!("silo::{org}::{pkg}::<{major}.{minor}.{patch}>::{s}")
47 }
48 None => format!("silo::{org}::{pkg}::<{major}.{minor}.{patch}>"),
49 },
50 }
51 }
52
53 pub fn to_idiom(&self) -> Idiom {
54 Idiom::field(self.to_string())
55 }
56}
57
58#[derive(Clone, Debug, PartialEq, Eq)]
59#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
60pub struct FunctionCall {
61 pub receiver: Function,
62 pub arguments: Vec<Expr>,
63}
64
65impl ToSql for FunctionCall {
66 fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
67 match self.receiver {
68 Function::Normal(ref s) => {
69 for (idx, s) in s.split("::").enumerate() {
70 if idx != 0 {
71 f.push_str("::");
72 } else {
73 write_sql!(f, fmt, "{}", EscapeIdent(s));
74 continue;
75 }
76 s.fmt_sql(f, fmt);
77 }
78 }
79 Function::Custom(ref s) => {
80 f.push_str("fn");
81 for s in s.split("::") {
82 f.push_str("::");
83 write_sql!(f, fmt, "{}", EscapeKwFreeIdent(s));
84 }
85 }
86 Function::Script(ref s) => {
87 write_sql!(
88 f,
89 fmt,
90 "function({}) {{{s}}}",
91 Fmt::comma_separated(self.arguments.iter().map(CoverStmts))
92 );
93 return;
94 }
95 Function::Model(ref m) => {
96 write_sql!(f, fmt, "{m}");
97 }
98 Function::Module(ref m, ref s) => {
99 f.push_str("mod::");
100 write_sql!(f, fmt, " {}", EscapeKwFreeIdent(m));
101 if let Some(s) = s {
102 for segment in s.split("::") {
103 write_sql!(f, fmt, "::{}", EscapeKwFreeIdent(segment));
104 }
105 }
106 }
107 Function::Silo {
108 ref org,
109 ref pkg,
110 ref major,
111 ref minor,
112 ref patch,
113 ref sub,
114 } => {
115 write_sql!(
116 f,
117 fmt,
118 "silo::{}::{}::<{major}.{minor}.{patch}>",
119 EscapeKwFreeIdent(org),
120 EscapeKwFreeIdent(pkg),
121 );
122 if let Some(s) = sub {
123 for segment in s.split("::") {
124 write_sql!(f, fmt, "::{}", EscapeKwFreeIdent(segment));
125 }
126 }
127 }
128 }
129 write_sql!(f, fmt, "({})", Fmt::comma_separated(self.arguments.iter().map(CoverStmts)))
130 }
131}