Skip to main content

sql_fun_sqlast/sem/
def_elem.rs

1use std::collections::HashMap;
2
3use crate::{
4    sem::{AnalysisError, AnalysisProblem, ParseContext},
5    syn::ListOpt,
6};
7
8/// key of `DefElem`
9#[derive(Debug, Clone, Eq, PartialEq, Hash)]
10pub struct DefElemKey {
11    namespace: String,
12    name: String,
13}
14
15impl DefElemKey {
16    fn new(namespace: &str, name: &str) -> Self {
17        Self {
18            namespace: namespace.to_string(),
19            name: name.to_string(),
20        }
21    }
22
23    /// strict `DefElem` name
24    #[must_use]
25    pub fn strict() -> Self {
26        Self::new("", "strict")
27    }
28}
29
30impl From<&crate::syn::DefElem> for DefElemKey {
31    fn from(value: &crate::syn::DefElem) -> Self {
32        Self::new(&value.get_defnamespace(), &value.get_defname())
33    }
34}
35
36/// hash map of `DefElem`
37#[derive(Debug, Clone, Default)]
38pub struct DefElemList(HashMap<DefElemKey, crate::syn::Node>);
39
40impl DefElemList {
41    /// test key exists
42    #[must_use]
43    pub fn contains(&self, key: &DefElemKey) -> bool {
44        self.0.contains_key(key)
45    }
46
47    /// get key value
48    #[must_use]
49    pub fn get(&self, key: &DefElemKey) -> Option<&crate::syn::Node> {
50        self.0.get(key)
51    }
52}
53
54/// analyze [`crate::syn::NodeListOpt`] as [`DefElemList`]
55pub fn analyze_def_elem_list<TParseContext>(
56    mut context: TParseContext,
57    syn: crate::syn::NodeListOpt,
58) -> Result<(DefElemList, TParseContext), AnalysisError>
59where
60    TParseContext: ParseContext,
61{
62    let Some(def_elem_list) = syn.map(|item| item.as_def_elem()) else {
63        return Ok((DefElemList::default(), context));
64    };
65
66    let mut items = HashMap::default();
67
68    for def_elem in def_elem_list {
69        let key = DefElemKey::from(&def_elem);
70        let arg = def_elem.get_arg();
71        if items.contains_key(&key) {
72            context.report_problem(AnalysisProblem::duplicate_def_elem_key(&key))?;
73        }
74        items.insert(key, arg);
75    }
76    Ok((DefElemList(items), context))
77}