1use byteorder::{BigEndian, ByteOrder};
4use escape_string::split_one;
5
6use crate::Timestamp;
7
8pub trait RowFormat {
10 fn to_stored_format(&self, ts: Timestamp, from: &str, dest: &mut Vec<u8>)
12 -> Result<(), String>;
13 fn elements(&self) -> &[Box<dyn Element>];
15 fn row_size(&self) -> Option<usize>;
19}
20
21struct RowFormatImpl {
22 size: Option<usize>,
23 elements: Vec<Box<dyn Element>>,
24}
25
26impl RowFormat for RowFormatImpl {
27 fn to_stored_format(
28 &self,
29 ts: Timestamp,
30 mut from: &str,
31 dest: &mut Vec<u8>,
32 ) -> Result<(), String> {
33 let at = dest.len();
34 dest.reserve(at + self.row_size().unwrap_or(0) + 8);
35 dest.resize(at + 8, 0);
36 BigEndian::write_u64(&mut dest[at..], ts);
37 for e in self.elements.iter() {
38 from = e.to_stored_format(from, dest)?;
39 }
40 if !from.is_empty() {
41 return Err("too many columns in input".to_string());
42 }
43 Ok(())
44 }
45 fn elements(&self) -> &[Box<dyn Element>] {
46 &self.elements
47 }
48 fn row_size(&self) -> Option<usize> {
49 Some(self.size? + 8)
50 }
51}
52
53pub fn parse_row_format(human: &str) -> Box<dyn RowFormat> {
71 let mut size = 0usize;
72 let mut has_size = true;
73 let mut elements: Vec<Box<dyn Element>> = Vec::with_capacity(human.len());
74
75 for t in human.bytes() {
76 match t {
77 b'i' => {
78 size += 4;
79 elements.push(Box::new(ElementI32));
80 }
81 b'u' => {
82 size += 4;
83 elements.push(Box::new(ElementU32));
84 }
85 b'I' => {
86 size += 8;
87 elements.push(Box::new(ElementI64));
88 }
89 b'U' => {
90 size += 8;
91 elements.push(Box::new(ElementU64));
92 }
93 b'f' => {
94 size += 4;
95 elements.push(Box::new(ElementF32));
96 }
97 b'F' => {
98 size += 8;
99 elements.push(Box::new(ElementF64));
100 }
101 b's' => {
102 has_size = false;
103 elements.push(Box::new(ElementString));
104 }
105 a => {
106 panic!("invalid format character '{}'", a);
107 }
108 }
109 }
110
111 Box::new(RowFormatImpl {
112 size: if has_size { Some(size) } else { None },
113 elements,
114 })
115}
116
117pub fn row_format_size(human: &str) -> Option<usize> {
118 let human = human.as_bytes();
119
120 let mut size = 0usize;
121
122 for t in human {
123 match t {
124 b'i' => size += 4,
125 b'u' => size += 4,
126 b'I' => size += 8,
127 b'U' => size += 8,
128 b'f' => size += 4,
129 b'F' => size += 8,
130 b's' => return None,
131 b'\x7f' => return None,
132 a => {
133 panic!("invalid format character '{}'", a);
134 }
135 }
136 }
137
138 Some(size)
139}
140
141pub trait Element {
142 fn to_stored_format<'s>(&self, from: &'s str, dest: &mut Vec<u8>) -> Result<&'s str, String>;
143 fn to_protocol_format<'a>(
144 &self,
145 from: &'a [u8],
146 dest: &mut dyn ::std::io::Write,
147 ) -> ::std::io::Result<&'a [u8]>;
148}
149
150struct ElementI32;
151impl Element for ElementI32 {
152 fn to_stored_format<'s>(&self, from: &'s str, dest: &mut Vec<u8>) -> Result<&'s str, String> {
153 let at = dest.len();
154 dest.resize(at + 4, 0);
155 let dest = &mut dest[at..];
156
157 let (t, rest) = split_one(from).unwrap();
158
159 let v = t
160 .parse()
161 .map_err(|e| format!("while parsing {}: {}", t, e))?;
162 BigEndian::write_i32(dest, v);
163
164 Ok(rest)
165 }
166 fn to_protocol_format<'a>(
167 &self,
168 from: &'a [u8],
169 dest: &mut dyn ::std::io::Write,
170 ) -> ::std::io::Result<&'a [u8]> {
171 let v: i32 = BigEndian::read_i32(&from[0..4]);
172 write!(dest, "{}", v)?;
173 Ok(&from[4..])
174 }
175}
176
177struct ElementU32;
178impl Element for ElementU32 {
179 fn to_stored_format<'s>(&self, from: &'s str, dest: &mut Vec<u8>) -> Result<&'s str, String> {
180 let at = dest.len();
181 dest.resize(at + 4, 0);
182 let dest = &mut dest[at..];
183
184 let (t, rest) = split_one(from).unwrap();
185
186 let v = t
187 .parse()
188 .map_err(|e| format!("while parsing {}: {}", t, e))?;
189 BigEndian::write_u32(dest, v);
190
191 Ok(rest)
192 }
193 fn to_protocol_format<'a>(
194 &self,
195 from: &'a [u8],
196 dest: &mut dyn ::std::io::Write,
197 ) -> ::std::io::Result<&'a [u8]> {
198 let v: u32 = BigEndian::read_u32(&from[0..4]);
199 write!(dest, "{}", v)?;
200 Ok(&from[4..])
201 }
202}
203
204struct ElementI64;
205impl Element for ElementI64 {
206 fn to_stored_format<'s>(&self, from: &'s str, dest: &mut Vec<u8>) -> Result<&'s str, String> {
207 let at = dest.len();
208 dest.resize(at + 8, 0);
209 let dest = &mut dest[at..];
210
211 let (t, rest) = split_one(from).unwrap();
212
213 let v = t
214 .parse()
215 .map_err(|e| format!("while parsing {}: {}", t, e))?;
216 BigEndian::write_i64(dest, v);
217
218 Ok(rest)
219 }
220 fn to_protocol_format<'a>(
221 &self,
222 from: &'a [u8],
223 dest: &mut dyn ::std::io::Write,
224 ) -> ::std::io::Result<&'a [u8]> {
225 let v: i64 = BigEndian::read_i64(&from[0..8]);
226 write!(dest, "{}", v)?;
227 Ok(&from[8..])
228 }
229}
230
231struct ElementU64;
232impl Element for ElementU64 {
233 fn to_stored_format<'s>(&self, from: &'s str, dest: &mut Vec<u8>) -> Result<&'s str, String> {
234 let at = dest.len();
235 dest.resize(at + 8, 0);
236 let dest = &mut dest[at..];
237
238 let (t, rest) = split_one(from).unwrap();
239
240 let v = t
241 .parse()
242 .map_err(|e| format!("while parsing {}: {}", t, e))?;
243 BigEndian::write_u64(dest, v);
244
245 Ok(rest)
246 }
247 fn to_protocol_format<'a>(
248 &self,
249 from: &'a [u8],
250 dest: &mut dyn ::std::io::Write,
251 ) -> ::std::io::Result<&'a [u8]> {
252 let v: u64 = BigEndian::read_u64(&from[0..8]);
253 write!(dest, "{}", v)?;
254 Ok(&from[8..])
255 }
256}
257
258struct ElementF32;
259impl Element for ElementF32 {
260 fn to_stored_format<'s>(&self, from: &'s str, dest: &mut Vec<u8>) -> Result<&'s str, String> {
261 let at = dest.len();
262 dest.resize(at + 4, 0);
263 let dest = &mut dest[at..];
264
265 let (t, rest) = split_one(from).unwrap();
266
267 let v = if t == "nan" {
268 ::std::f32::NAN
269 } else {
270 t.parse()
271 .map_err(|e| format!("while parsing {}: {}", t, e))?
272 };
273 BigEndian::write_f32(dest, v);
274
275 Ok(rest)
276 }
277 fn to_protocol_format<'a>(
278 &self,
279 from: &'a [u8],
280 dest: &mut dyn ::std::io::Write,
281 ) -> ::std::io::Result<&'a [u8]> {
282 let v: f32 = BigEndian::read_f32(&from[0..4]);
283 write!(dest, "{:.17}", v)?;
284 Ok(&from[4..])
285 }
286}
287
288struct ElementF64;
289impl Element for ElementF64 {
290 fn to_stored_format<'s>(&self, from: &'s str, dest: &mut Vec<u8>) -> Result<&'s str, String> {
291 let at = dest.len();
292 dest.resize(at + 8, 0);
293 let dest = &mut dest[at..];
294
295 let (t, rest) = split_one(from).unwrap();
296
297 let v = if t == "nan" {
298 ::std::f64::NAN
299 } else {
300 t.parse()
301 .map_err(|e| format!("while parsing {}: {}", t, e))?
302 };
303 BigEndian::write_f64(dest, v);
304
305 Ok(rest)
306 }
307 fn to_protocol_format<'a>(
308 &self,
309 from: &'a [u8],
310 dest: &mut dyn ::std::io::Write,
311 ) -> ::std::io::Result<&'a [u8]> {
312 let v: f64 = BigEndian::read_f64(&from[0..8]);
313 write!(dest, "{:.17}", v)?;
314 Ok(&from[8..])
315 }
316}
317
318pub(crate) struct ElementString;
319impl Element for ElementString {
320 fn to_stored_format<'s>(&self, from: &'s str, dest: &mut Vec<u8>) -> Result<&'s str, String> {
321 let (head, tail) = escape_string::split_one(from)
322 .ok_or_else(|| format!("Unable to parse \"{}\" as backslash-escaped string", from))?;
323 let mut buf = unsigned_varint::encode::u64_buffer();
324 let encoded_len = unsigned_varint::encode::u64(head.len() as u64, &mut buf);
325 dest.extend_from_slice(encoded_len);
326 dest.extend_from_slice(head.as_bytes());
327 Ok(tail)
328 }
329 fn to_protocol_format<'a>(
330 &self,
331 from: &'a [u8],
332 dest: &mut dyn ::std::io::Write,
333 ) -> ::std::io::Result<&'a [u8]> {
334 let (len, tail) = unsigned_varint::decode::u64(from).map_err(|e| {
335 std::io::Error::new(std::io::ErrorKind::InvalidData, format!("{:?}", e))
336 })?;
337
338 let s = std::str::from_utf8(&tail[0..len as usize])
339 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
340 write!(dest, "{}", escape_string::escape(s))?;
341 Ok(&tail[len as usize..])
342 }
343}