Skip to main content

sql_fun_sqlast/sem/names/full/
impl_coversion_traits.rs

1use crate::{
2    sem::{AnalysisError, CatalogName, LocalName, SchemaName},
3    syn::{ListOpt, NodeListOpt, RangeVar, TypeName},
4};
5
6use super::FullName;
7
8impl TryFrom<NodeListOpt> for FullName {
9    type Error = AnalysisError;
10
11    fn try_from(value: NodeListOpt) -> Result<Self, Self::Error> {
12        let Some(name_elements) = value.map(|v| v.as_string()) else {
13            AnalysisError::raise_unexpected_none("node_list")?
14        };
15        let elements: Vec<String> = name_elements
16            .iter()
17            .map(crate::syn::String::get_sval)
18            .collect();
19        match elements.len() {
20            3 => Ok(Self {
21                catalog: Some(CatalogName::from(&elements[0])),
22                schema: Some(SchemaName::from(&elements[1])),
23                name: LocalName::from(&elements[2]),
24            }),
25            2 => Ok(Self {
26                catalog: None,
27                schema: Some(SchemaName::from(&elements[0])),
28                name: LocalName::from(&elements[1]),
29            }),
30            1 => Ok(Self {
31                catalog: None,
32                schema: None,
33                name: LocalName::from(&elements[0]),
34            }),
35            _ => Err(AnalysisError::type_name_format(&elements)),
36        }
37    }
38}
39
40impl TryFrom<RangeVar> for FullName {
41    type Error = AnalysisError;
42
43    fn try_from(value: RangeVar) -> Result<Self, Self::Error> {
44        let catalog = value.get_catalogname();
45        let schema = value.get_schemaname();
46        let name = value.get_relname();
47        Ok(Self {
48            catalog: {
49                if catalog.is_empty() {
50                    None
51                } else {
52                    Some(CatalogName::from(&catalog))
53                }
54            },
55            schema: {
56                if schema.is_empty() {
57                    None
58                } else {
59                    Some(SchemaName::from(&schema))
60                }
61            },
62            name: LocalName::from(&name),
63        })
64    }
65}
66
67impl TryFrom<TypeName> for FullName {
68    type Error = AnalysisError;
69
70    fn try_from(value: TypeName) -> Result<Self, Self::Error> {
71        let Some(names) = value.get_names().map(|v| v.as_string()) else {
72            AnalysisError::raise_unexpected_none("type_name.names")?
73        };
74        let names: Vec<String> = names.iter().map(crate::syn::String::get_sval).collect();
75
76        match names.len() {
77            3 => Ok(Self {
78                catalog: Some(CatalogName::from(&names[0])),
79                schema: Some(SchemaName::from(&names[1])),
80                name: LocalName::from(&names[2]),
81            }),
82            2 => Ok(Self {
83                catalog: None,
84                schema: Some(SchemaName::from(&names[0])),
85                name: LocalName::from(&names[1]),
86            }),
87            1 => Ok(Self {
88                catalog: None,
89                schema: None,
90                name: LocalName::from(&names[0]),
91            }),
92            _ => Err(AnalysisError::type_name_format(&names)),
93        }
94    }
95}
96
97impl std::str::FromStr for FullName {
98    type Err = AnalysisError;
99
100    fn from_str(s: &str) -> Result<Self, Self::Err> {
101        let parts: Vec<&str> = s.split('.').collect();
102        if parts.len() == 3 {
103            Ok(Self {
104                catalog: Some(CatalogName::from(parts[0])),
105                schema: Some(SchemaName::from(parts[1])),
106                name: LocalName::from(parts[2]),
107            })
108        } else if parts.len() == 2 {
109            Ok(Self {
110                catalog: None,
111                schema: Some(SchemaName::from(parts[0])),
112                name: LocalName::from(parts[1]),
113            })
114        } else {
115            Ok(Self {
116                catalog: None,
117                schema: None,
118                name: LocalName::from(parts[0]),
119            })
120        }
121    }
122}