gluesql_core/ast/
ast_literal.rs

1use {
2    crate::ast::ToSql,
3    bigdecimal::BigDecimal,
4    serde::{Deserialize, Serialize},
5    strum_macros::Display,
6};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub enum AstLiteral {
10    Boolean(bool),
11    Number(BigDecimal),
12    QuotedString(String),
13    HexString(String),
14    Null,
15}
16
17impl ToSql for AstLiteral {
18    fn to_sql(&self) -> String {
19        match self {
20            AstLiteral::Boolean(b) => b.to_string().to_uppercase(),
21            AstLiteral::Number(n) => n.to_string(),
22            AstLiteral::QuotedString(qs) => {
23                let escaped = qs.replace('\'', "''");
24                format!("'{escaped}'")
25            }
26            AstLiteral::HexString(hs) => format!("'{hs}'"),
27            AstLiteral::Null => "NULL".to_owned(),
28        }
29    }
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Display)]
33#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
34pub enum DateTimeField {
35    Year,
36    Month,
37    Day,
38    Hour,
39    Minute,
40    Second,
41}
42
43#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Display)]
44#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
45pub enum TrimWhereField {
46    Both,
47    Leading,
48    Trailing,
49}
50
51#[cfg(test)]
52mod tests {
53    use {
54        crate::ast::{AstLiteral, ToSql},
55        bigdecimal::BigDecimal,
56    };
57
58    #[test]
59    fn to_sql() {
60        assert_eq!("TRUE", AstLiteral::Boolean(true).to_sql());
61        assert_eq!("123", AstLiteral::Number(BigDecimal::from(123)).to_sql());
62        assert_eq!(
63            "'hello'",
64            AstLiteral::QuotedString("hello".to_owned()).to_sql()
65        );
66        assert_eq!(
67            "'can''t'",
68            AstLiteral::QuotedString("can't".to_owned()).to_sql()
69        );
70        assert_eq!("NULL", AstLiteral::Null.to_sql());
71    }
72}