sql_fun_sqlast/sem/
def_elem.rs1use std::collections::HashMap;
2
3use crate::{
4 sem::{AnalysisError, AnalysisProblem, ParseContext},
5 syn::ListOpt,
6};
7
8#[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 #[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#[derive(Debug, Clone, Default)]
38pub struct DefElemList(HashMap<DefElemKey, crate::syn::Node>);
39
40impl DefElemList {
41 #[must_use]
43 pub fn contains(&self, key: &DefElemKey) -> bool {
44 self.0.contains_key(key)
45 }
46
47 #[must_use]
49 pub fn get(&self, key: &DefElemKey) -> Option<&crate::syn::Node> {
50 self.0.get(key)
51 }
52}
53
54pub 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}