Skip to main content

tank_core/writer/
context.rs

1use crate::TableRef;
2use std::borrow::Cow;
3
4#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
5pub enum Fragment {
6    #[default]
7    None,
8    Aliasing,
9    ParameterBinding,
10    Casting,
11    Json,
12    JsonKey,
13    SqlCommentOnColumn,
14    SqlCreateSchema,
15    SqlCreateTable,
16    SqlCreateTablePrimaryKey,
17    SqlCreateTableUnique,
18    SqlDeleteFrom,
19    SqlDeleteFromWhere,
20    SqlDropSchema,
21    SqlDropTable,
22    SqlInsertInto,
23    SqlInsertIntoOnConflict,
24    SqlInsertIntoValues,
25    SqlJoin,
26    SqlSelect,
27    SqlSelectFrom,
28    SqlSelectGroupBy,
29    SqlSelectHaving,
30    SqlSelectOrderBy,
31    SqlSelectWhere,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct Context {
36    pub counter: u32,
37    pub fragment: Fragment,
38    pub table_ref: TableRef,
39    pub qualify_columns: bool,
40    pub quote_identifiers: bool,
41}
42
43impl Context {
44    pub const fn new(fragment: Fragment, qualify_columns: bool) -> Self {
45        Self {
46            counter: 0,
47            fragment,
48            table_ref: TableRef::new(Cow::Borrowed("")),
49            qualify_columns,
50            quote_identifiers: true,
51        }
52    }
53    pub const fn empty() -> Self {
54        Self {
55            counter: 0,
56            fragment: Fragment::None,
57            table_ref: TableRef::new(Cow::Borrowed("")),
58            qualify_columns: false,
59            quote_identifiers: false,
60        }
61    }
62    pub const fn fragment(fragment: Fragment) -> Self {
63        Self {
64            counter: 0,
65            fragment,
66            table_ref: TableRef::new(Cow::Borrowed("")),
67            qualify_columns: false,
68            quote_identifiers: true,
69        }
70    }
71    pub const fn qualify(qualify_columns: bool) -> Self {
72        Self {
73            counter: 0,
74            fragment: Fragment::None,
75            table_ref: TableRef::new(Cow::Borrowed("")),
76            qualify_columns,
77            quote_identifiers: true,
78        }
79    }
80    pub const fn qualify_with(table: Cow<'static, str>) -> Self {
81        Self {
82            counter: 0,
83            fragment: Fragment::None,
84            table_ref: TableRef::new(table),
85            qualify_columns: true,
86            quote_identifiers: true,
87        }
88    }
89    pub const fn update_from(&mut self, context: &Context) {
90        self.counter = context.counter;
91    }
92    pub fn switch_fragment<'s>(&'s mut self, fragment: Fragment) -> ContextUpdater<'s> {
93        ContextUpdater {
94            current: Context {
95                fragment,
96                table_ref: self.table_ref.clone(),
97                ..*self
98            },
99            previous: self,
100        }
101    }
102    pub fn switch_table<'s>(&'s mut self, table_ref: TableRef) -> ContextUpdater<'s> {
103        let is_empty = table_ref.is_empty();
104        ContextUpdater {
105            current: Context {
106                table_ref,
107                qualify_columns: !is_empty,
108                ..*self
109            },
110            previous: self,
111        }
112    }
113    pub fn is_inside_json(&self) -> bool {
114        self.fragment == Fragment::Json || self.fragment == Fragment::JsonKey
115    }
116}
117
118impl Default for Context {
119    fn default() -> Self {
120        Context::new(Fragment::None, true)
121    }
122}
123
124pub struct ContextUpdater<'a> {
125    pub current: Context,
126    pub previous: &'a mut Context,
127}
128
129impl<'a> Drop for ContextUpdater<'a> {
130    fn drop(&mut self) {
131        self.previous.counter = self.current.counter;
132    }
133}