assembly_data/xml/database/
mod.rs1use assembly_core::displaydoc::Display;
8use quick_xml::{events::Event, Reader};
9use std::{collections::HashMap, error::Error, fmt, io::BufRead, str::FromStr};
10
11use super::common::{expect_elem, expect_named_elem, XmlError};
12
13#[cfg(feature = "serde-derives")]
14use serde::{
15 de::{self, Unexpected, Visitor},
16 Deserialize, Deserializer,
17};
18
19#[derive(Debug, Copy, Clone, PartialEq, Eq)]
26pub enum ValueType {
27 Bit,
29
30 Float,
32 Real,
34
35 Int,
37 BigInt,
39 SmallInt,
41 TinyInt,
43
44 Binary,
46 VarBinary,
48
49 Char,
51 VarChar,
53
54 NChar,
56 NVarChar,
58
59 NText,
61 Text,
63 Image,
65
66 DateTime,
68}
69
70impl<'de> Deserialize<'de> for ValueType {
71 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
72 where
73 D: Deserializer<'de>,
74 {
75 deserializer.deserialize_str(ValueTypeVisitor)
76 }
77}
78
79#[derive(Debug, Display)]
80pub struct UnknownValueType(String);
82
83impl Error for UnknownValueType {}
84
85impl FromStr for ValueType {
86 type Err = UnknownValueType;
87
88 fn from_str(s: &str) -> Result<Self, Self::Err> {
89 match s {
90 "bit" => Ok(Self::Bit),
91
92 "float" => Ok(Self::Float),
93 "real" => Ok(Self::Real),
94
95 "int" => Ok(Self::Int),
96 "bigint" => Ok(Self::BigInt),
97 "smallint" => Ok(Self::SmallInt),
98 "tinyint" => Ok(Self::TinyInt),
99
100 "binary" => Ok(Self::Binary),
101 "varbinary" => Ok(Self::VarBinary),
102
103 "char" => Ok(Self::Char),
104 "varchar" => Ok(Self::VarChar),
105
106 "nchar" => Ok(Self::NChar),
107 "nvarchar" => Ok(Self::NVarChar),
108
109 "text" => Ok(Self::Text),
110 "ntext" => Ok(Self::NText),
111 "image" => Ok(Self::Image),
112
113 "datetime" => Ok(Self::DateTime),
114
115 _ => Err(UnknownValueType(s.to_owned())),
116 }
117 }
118}
119
120#[cfg(feature = "serde-derives")]
121struct ValueTypeVisitor;
122
123#[cfg(feature = "serde-derives")]
124impl<'de> Visitor<'de> for ValueTypeVisitor {
125 type Value = ValueType;
126
127 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
128 formatter.write_str("T-SQL value type")
129 }
130
131 fn visit_str<E>(self, value: &str) -> Result<ValueType, E>
132 where
133 E: de::Error,
134 {
135 FromStr::from_str(value)
136 .map_err(|_| E::invalid_value(Unexpected::Other(value), &"T-SQL value type"))
137 }
138}
139
140#[cfg_attr(feature = "serde-derives", derive(Deserialize))]
142#[derive(Debug, Eq, PartialEq)]
143pub struct Row(HashMap<String, String>);
144
145pub fn expect_database<B: BufRead>(
147 xml: &mut Reader<B>,
148 buf: &mut Vec<u8>,
149) -> Result<Option<String>, XmlError> {
150 expect_named_elem(xml, buf, "database", None)
151}
152
153pub fn expect_table<B: BufRead>(
155 xml: &mut Reader<B>,
156 buf: &mut Vec<u8>,
157) -> Result<Option<String>, XmlError> {
158 expect_named_elem(xml, buf, "table", Some("database"))
159}
160
161pub fn expect_columns<B: BufRead>(xml: &mut Reader<B>, buf: &mut Vec<u8>) -> Result<(), XmlError> {
163 expect_elem(xml, buf, "columns")
164}
165
166pub fn expect_rows<B: BufRead>(xml: &mut Reader<B>, buf: &mut Vec<u8>) -> Result<(), XmlError> {
168 expect_elem(xml, buf, "rows")
169}
170
171#[cfg_attr(feature = "serde-derives", derive(Deserialize))]
173pub struct Column {
174 pub name: String,
176 pub r#type: ValueType,
178}
179
180pub fn expect_column_or_end_columns<B: BufRead>(
189 xml: &mut Reader<B>,
190 buf: &mut Vec<u8>,
191) -> Result<Option<Column>, XmlError> {
192 match xml.read_event(buf)? {
193 Event::Empty(start) => {
194 if start.name() == b"column" {
195 let mut name = None;
196 let mut data_type = None;
197 for attr in start.attributes() {
198 let attr = attr?;
199 if attr.key == b"name" {
200 name = Some(xml.decode(&attr.value).into_owned());
201 }
202
203 if attr.key == b"type" {
204 data_type = Some(
205 xml.decode(&attr.value)
206 .parse()
207 .expect("Expected well-known value type"),
208 );
209 }
210 }
211 buf.clear();
212 Ok(Some(Column {
213 name: name.unwrap(),
214 r#type: data_type.unwrap(),
215 }))
216 } else {
217 todo!();
218 }
219 }
220 Event::End(v) => {
221 assert_eq!(v.name(), b"columns");
222 Ok(None)
223 }
224 Event::Eof => Err(XmlError::EofWhileExpecting("column")),
225 x => panic!("What? {:?}", x),
226 }
227}
228
229pub fn expect_row_or_end_rows<B: BufRead>(
231 xml: &mut Reader<B>,
232 buf: &mut Vec<u8>,
233 load_attrs: bool,
234) -> Result<Option<HashMap<String, String>>, XmlError> {
235 match xml.read_event(buf)? {
236 Event::Empty(start) => {
237 if start.name() == b"row" {
238 let map = if load_attrs {
239 let mut m = HashMap::new();
240 for attr in start.attributes() {
241 let attr = attr?;
242 let key = xml.decode(attr.key).into_owned();
243 let value = attr.unescape_and_decode_value(xml)?;
244 m.insert(key, value);
245 }
246 m
247 } else {
248 HashMap::new()
249 };
250 buf.clear();
251 Ok(Some(map))
252 } else {
253 todo!();
254 }
255 }
256 Event::End(v) => {
257 assert_eq!(v.name(), b"rows");
258 Ok(None)
259 }
260 _ => todo!(),
261 }
262}
263
264#[cfg(test)]
265mod tests {
266 use quick_xml::{de::Deserializer, DeError};
267
268 use super::*;
269 use quick_xml::Error as XmlError;
270 use std::io::BufReader;
271 use std::io::Cursor;
272
273 #[test]
274 fn test_simple_deserialize() {
275 let st = br#"<row foo="bar"/></rows>"#;
276 let c = BufReader::new(Cursor::new(st));
277 let mut d = Deserializer::from_reader(c);
278 let row = Row::deserialize(&mut d).unwrap();
279 let mut cmp = HashMap::new();
280 let key = String::from("foo");
281 let val = String::from("bar");
282 cmp.insert(key, val);
283 assert_eq!(row.0, cmp);
284
285 if let Err(DeError::Xml(XmlError::EndEventMismatch { expected, found })) =
286 Row::deserialize(&mut d)
287 {
288 assert_eq!(&expected, "");
289 assert_eq!(&found, "rows");
290 }
291 }
292}