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