sql_fun_sqlast/sem/names/
ope.rs1use std::fmt::Display;
2
3use crate::{
4 sem::{AnalysisError, ParseContext, error::ProblemLikeError},
5 syn::{ListOpt, NodeListOpt},
6};
7
8use super::SchemaName;
9
10#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
12pub struct ValidOperatorName {
13 schema_name: Option<SchemaName>,
14 op_name: String,
15}
16
17impl Display for ValidOperatorName {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 if let Some(schema_name) = &self.schema_name {
20 write!(f, "{schema_name}",)?;
21 }
22 write!(f, "{}", self.op_name)?;
23 Ok(())
24 }
25}
26
27impl ValidOperatorName {
28 pub fn try_from(value: NodeListOpt) -> Result<Option<Self>, ProblemLikeError> {
30 let Some(items) = value.map_values(|v| v.as_string().get_sval()) else {
31 return Ok(None);
32 };
33 if items.is_empty() || items.len() >= 2 {
34 Err(ProblemLikeError::invalid_operator_name(items))?
35 } else if items.len() == 1 {
36 Ok(Some(ValidOperatorName {
37 schema_name: None,
38 op_name: items[0].clone(),
39 }))
40 } else {
41 Ok(Some(ValidOperatorName {
42 schema_name: Some(SchemaName::from(items[0].as_str())),
43 op_name: items[1].clone(),
44 }))
45 }
46 }
47
48 #[cfg(test)]
50 pub fn new(operator_name: &str) -> Self {
51 Self {
52 schema_name: None,
53 op_name: String::from(operator_name),
54 }
55 }
56}
57
58#[derive(Debug, Clone, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
60pub enum OperatorName {
61 Valid(ValidOperatorName),
63 Invalid,
65}
66
67impl OperatorName {
68 pub fn try_from_report<TParseContext: ParseContext>(
70 value: NodeListOpt,
71 context: &mut TParseContext,
72 ) -> Result<Option<Self>, AnalysisError> {
73 let result = ValidOperatorName::try_from(value);
74 match result {
75 Ok(Some(v)) => Ok(Some(Self::Valid(v))),
76 Ok(None) => Ok(None),
77 Err(e) => {
78 e.report_problem_to(context)?;
79 Ok(Some(Self::Invalid))
80 }
81 }
82 }
83
84 #[must_use]
86 pub fn is_valid(&self) -> bool {
87 matches!(self, Self::Valid(_))
88 }
89
90 #[must_use]
92 pub fn to_name_string(&self) -> String {
93 match self {
94 Self::Valid(v) => v.to_string(),
95 _ => panic!("invalid name"),
96 }
97 }
98}