surql_parser/upstream/sql/
idiom.rs1use crate::upstream::fmt::{EscapeIdent, Fmt};
2use crate::upstream::sql::{Expr, Literal, Part};
3use std::ops::Deref;
4use surrealdb_types::{SqlFormat, ToSql, write_sql};
5#[derive(Clone, Debug, Default, Eq, PartialEq)]
6#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
7#[allow(dead_code)]
8pub struct Idioms(pub Vec<Idiom>);
9impl Deref for Idioms {
10 type Target = Vec<Idiom>;
11 fn deref(&self) -> &Self::Target {
12 &self.0
13 }
14}
15impl IntoIterator for Idioms {
16 type Item = Idiom;
17 type IntoIter = std::vec::IntoIter<Self::Item>;
18 fn into_iter(self) -> Self::IntoIter {
19 self.0.into_iter()
20 }
21}
22impl ToSql for Idioms {
23 fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
24 write_sql!(f, fmt, "{}", Fmt::comma_separated(&self.0))
25 }
26}
27#[derive(Clone, Debug, Default, PartialEq, Eq)]
28pub struct Idiom(pub Vec<Part>);
29impl Idiom {
30 pub fn simplify(&self) -> Idiom {
32 Idiom(
33 self.0
34 .iter()
35 .filter(|&p| matches!(p, Part::Field(_) | Part::Start(_) | Part::Graph(_)))
36 .cloned()
37 .collect(),
38 )
39 }
40 pub fn field(name: String) -> Self {
41 Idiom(vec![Part::Field(name)])
42 }
43}
44impl surrealdb_types::ToSql for Idiom {
45 fn fmt_sql(&self, f: &mut String, fmt: surrealdb_types::SqlFormat) {
46 let mut iter = self.0.iter();
47 match iter.next() {
48 Some(Part::Field(v)) => EscapeIdent(v).fmt_sql(f, fmt),
49 Some(Part::Start(x)) => {
50 if x.needs_parentheses()
51 || matches!(
52 x,
53 Expr::Binary { .. } | Expr::Prefix { .. } | Expr::Postfix { .. }
54 ) {
55 write_sql!(f, fmt, "({x})");
56 } else if let Expr::Literal(Literal::Decimal(d)) = x
57 && d.is_sign_negative()
58 {
59 write_sql!(f, fmt, "({x})");
60 } else if let Expr::Literal(Literal::Integer(i)) = x
61 && i.is_negative()
62 {
63 write_sql!(f, fmt, "({x})");
64 } else if let Expr::Literal(Literal::Float(float)) = x
65 && float.is_sign_negative()
66 {
67 write_sql!(f, fmt, "({x})");
68 } else {
69 write_sql!(f, fmt, "{x}");
70 }
71 }
72 Some(x) => x.fmt_sql(f, fmt),
73 None => {}
74 };
75 for p in iter {
76 p.fmt_sql(f, fmt);
77 }
78 }
79}