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