proof_of_sql/base/database/
table_ref.rs1use crate::base::database::error::ParseError;
2use alloc::{string::ToString, vec::Vec};
3use core::{
4 fmt,
5 fmt::{Display, Formatter},
6 str::FromStr,
7};
8use indexmap::Equivalent;
9use serde::{Deserialize, Serialize};
10use sqlparser::ast::Ident;
11
12#[derive(Debug, Clone, PartialEq, Eq, Hash)]
14pub struct TableRef {
15 schema_name: Option<Ident>,
16 table_name: Ident,
17}
18
19impl TableRef {
20 #[must_use]
23 pub fn new(schema_name: impl AsRef<str>, table_name: impl AsRef<str>) -> Self {
24 let schema = schema_name.as_ref();
25 let table = table_name.as_ref();
26
27 Self {
28 schema_name: if schema.is_empty() {
29 None
30 } else {
31 Some(Ident::new(schema.to_string()))
32 },
33 table_name: Ident::new(table.to_string()),
34 }
35 }
36
37 #[must_use]
40 pub fn schema_id(&self) -> Option<&Ident> {
41 self.schema_name.as_ref()
42 }
43
44 #[must_use]
47 pub fn table_id(&self) -> &Ident {
48 &self.table_name
49 }
50
51 #[must_use]
53 pub fn from_names(schema_name: Option<&str>, table_name: &str) -> Self {
54 Self {
55 schema_name: schema_name.map(|s| Ident::new(s.to_string())),
56 table_name: Ident::new(table_name.to_string()),
57 }
58 }
59
60 #[must_use]
62 pub fn from_idents(schema_name: Option<Ident>, table_name: Ident) -> Self {
63 Self {
64 schema_name,
65 table_name,
66 }
67 }
68
69 pub fn from_strs<S: AsRef<str>>(components: &[S]) -> Result<Self, ParseError> {
71 match components.len() {
72 1 => Ok(Self::from_names(None, components[0].as_ref())),
73 2 => Ok(Self::from_names(
74 Some(components[0].as_ref()),
75 components[1].as_ref(),
76 )),
77 _ => Err(ParseError::InvalidTableReference {
78 table_reference: components
79 .iter()
80 .map(AsRef::as_ref)
81 .collect::<Vec<_>>()
82 .join(","),
83 }),
84 }
85 }
86}
87
88impl TryFrom<&str> for TableRef {
90 type Error = ParseError;
91
92 fn try_from(s: &str) -> Result<Self, <Self as TryFrom<&str>>::Error> {
93 let components: Vec<_> = s.split('.').map(ToString::to_string).collect();
94 match components.len() {
95 1 => Ok(Self::from_names(None, &components[0])),
96 2 => Ok(Self::from_names(Some(&components[0]), &components[1])),
97 _ => Err(ParseError::InvalidTableReference {
98 table_reference: s.to_string(),
99 }),
100 }
101 }
102}
103
104impl FromStr for TableRef {
105 type Err = ParseError;
106
107 fn from_str(s: &str) -> Result<Self, Self::Err> {
108 Self::try_from(s)
109 }
110}
111
112impl Equivalent<TableRef> for &TableRef {
113 fn equivalent(&self, key: &TableRef) -> bool {
114 self.schema_name == key.schema_name && self.table_name == key.table_name
115 }
116}
117
118impl Display for TableRef {
119 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
120 if let Some(schema) = &self.schema_name {
121 write!(f, "{}.{}", schema.value, self.table_name.value)
122 } else {
123 write!(f, "{}", self.table_name.value)
124 }
125 }
126}
127
128impl Serialize for TableRef {
129 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
130 where
131 S: serde::Serializer,
132 {
133 serializer.serialize_str(&self.to_string())
134 }
135}
136impl<'d> Deserialize<'d> for TableRef {
137 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
138 where
139 D: serde::Deserializer<'d>,
140 {
141 let string = alloc::string::String::deserialize(deserializer)?;
142 TableRef::from_str(&string).map_err(serde::de::Error::custom)
143 }
144}