Skip to main content

sql_fun_sqlast/sem/names/
full.rs

1mod impl_coversion_traits;
2
3use std::fmt::Display;
4
5use crate::sem::{CatalogName, LocalName, SchemaName};
6
7/// full name parts.
8#[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
9pub struct FullName {
10    catalog: Option<CatalogName>,
11    schema: Option<SchemaName>,
12    name: LocalName,
13}
14
15impl FullName {
16    /// create instance
17    #[must_use]
18    pub fn new(
19        catalog: &Option<CatalogName>,
20        schema: &Option<SchemaName>,
21        name: &LocalName,
22    ) -> Self {
23        Self {
24            catalog: catalog.clone(),
25            schema: schema.clone(),
26            name: name.clone(),
27        }
28    }
29
30    /// get `local_name` part as String
31    #[must_use]
32    pub fn local_name(&self) -> String {
33        self.name.to_string()
34    }
35
36    /// get catalog part
37    #[must_use]
38    pub fn catalog(&self) -> Option<&CatalogName> {
39        self.catalog.as_ref()
40    }
41
42    /// get schema part
43    #[must_use]
44    pub fn schema(&self) -> Option<&SchemaName> {
45        self.schema.as_ref()
46    }
47
48    /// get local-name as [`LocalName`]
49    #[must_use]
50    pub fn name(&self) -> &LocalName {
51        &self.name
52    }
53
54    /// create with catalog
55    pub fn with_catalog(catalog: &str, schema: Option<&str>, name: &str) -> Self {
56        Self {
57            catalog: Some(CatalogName::from(catalog)),
58            schema: schema.map(SchemaName::from),
59            name: LocalName::from(name),
60        }
61    }
62
63    /// create with schema
64    #[must_use]
65    pub fn with_schema(schema: &str, local: &str) -> Self {
66        Self {
67            catalog: None,
68            schema: Some(SchemaName::from(schema)),
69            name: LocalName::from(local),
70        }
71    }
72
73    /// set schema
74    #[must_use]
75    pub fn set_schema(mut self, schema: SchemaName) -> Self {
76        self.schema = Some(schema);
77        self
78    }
79
80    /// returns schema replaced full name
81    #[must_use]
82    pub fn replace_schema(&self, schema: &SchemaName) -> Self {
83        self.clone().set_schema(schema.clone())
84    }
85
86    /// supply `catalog_name`
87    #[must_use]
88    pub fn catalog_default(&self, catalog_name: &str) -> FullName {
89        if self.catalog().is_none() && self.schema().is_none() {
90            FullName::with_catalog(catalog_name, None, self.name().as_str())
91        } else {
92            self.clone()
93        }
94    }
95
96    /// create `FullName` from only local part
97    #[must_use]
98    pub fn from_local_name(local_name: &str) -> FullName {
99        Self {
100            catalog: None,
101            schema: None,
102            name: LocalName::from(local_name),
103        }
104    }
105
106    /// builtin record type
107    #[must_use]
108    pub fn is_record(&self) -> bool {
109        self.schema
110            .as_ref()
111            .is_some_and(super::schema::SchemaName::is_pg_catalog)
112            && self.name.is_record()
113    }
114
115    /// is range type?
116    #[must_use]
117    pub fn is_range(&self) -> bool {
118        !self.is_multi_range() && self.local_name().as_str().ends_with("range")
119    }
120
121    /// get subtype from range type
122    #[must_use]
123    pub fn range_subtype(&self) -> Self {
124        todo!()
125    }
126
127    /// is multi range type?
128    #[must_use]
129    pub fn is_multi_range(&self) -> bool {
130        self.local_name().as_str().ends_with("multirange")
131    }
132
133    /// get base element type from multi range type
134    #[must_use]
135    pub fn multi_range_base_element(&self) -> Self {
136        todo!()
137    }
138
139    /// is simple infrence types
140    #[must_use]
141    pub fn is_simple_infer_arg(&self) -> bool {
142        self.is_any_array()
143            || self.is_any_element()
144            || self.is_any_range()
145            || self.is_any_multi_range()
146            || self.is_any_non_array()
147    }
148
149    /// is common inference types
150    #[must_use]
151    pub fn is_common_infer_arg(&self) -> bool {
152        self.is_any_compatible()
153            || self.is_any_compatible_array()
154            || self.is_any_compatible_non_array()
155            || self.is_any_compatible_range()
156            || self.is_any_compatible_multi_range()
157    }
158
159    fn schema_is_pg_catalog(&self) -> bool {
160        self.schema
161            .as_ref()
162            .is_some_and(super::schema::SchemaName::is_pg_catalog)
163    }
164
165    /// just anyarray type
166    #[must_use]
167    pub fn is_any_array(&self) -> bool {
168        self.schema_is_pg_catalog() && self.name == LocalName::from("anyarray")
169    }
170
171    /// just anyelement type
172    #[must_use]
173    pub fn is_any_element(&self) -> bool {
174        self.schema_is_pg_catalog() && self.name == LocalName::from("anyelement")
175    }
176
177    /// just anyrange type
178    #[must_use]
179    pub fn is_any_range(&self) -> bool {
180        self.schema_is_pg_catalog() && self.name == LocalName::from("anyrange")
181    }
182
183    /// just anymultirange
184    #[must_use]
185    pub fn is_any_multi_range(&self) -> bool {
186        self.schema_is_pg_catalog() && self.name == LocalName::from("anymultirange")
187    }
188
189    /// just anynonarray
190    #[must_use]
191    pub fn is_any_non_array(&self) -> bool {
192        self.schema_is_pg_catalog() && self.name == LocalName::from("anynonarray")
193    }
194
195    /// just anycompatible
196    #[must_use]
197    pub fn is_any_compatible(&self) -> bool {
198        self.schema_is_pg_catalog() && self.name == LocalName::from("anycompatible")
199    }
200
201    /// just anycompatiblearray
202    #[must_use]
203    pub fn is_any_compatible_array(&self) -> bool {
204        self.schema_is_pg_catalog() && self.name == LocalName::from("anycompatiblearray")
205    }
206
207    /// just anycompatiblenonarray
208    #[must_use]
209    pub fn is_any_compatible_non_array(&self) -> bool {
210        self.schema_is_pg_catalog() && self.name == LocalName::from("anycompatiblenonarray")
211    }
212
213    /// just anycompatiblerange
214    #[must_use]
215    pub fn is_any_compatible_range(&self) -> bool {
216        self.schema_is_pg_catalog() && self.name == LocalName::from("anycompatiblerange")
217    }
218
219    /// just anycompatiblemultirange
220    #[must_use]
221    pub fn is_any_compatible_multi_range(&self) -> bool {
222        self.schema_is_pg_catalog() && self.name == LocalName::from("anycompatiblemultirange")
223    }
224}
225
226impl Display for FullName {
227    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
228        if let Some(catalog) = &self.catalog {
229            write!(f, "{catalog}.")?;
230        }
231
232        if let Some(schema) = &self.schema {
233            write!(f, "{schema}.")?;
234        }
235
236        write!(f, "{}", self.name)
237    }
238}