1use crate::{
10 io::ParseBuf,
11 misc::unexpected_buf_eof,
12 packets::{Column, NullBitmap},
13 proto::{Binary, MyDeserialize, Text},
14 value::{
15 convert::{from_value, from_value_opt, FromValue, FromValueError},
16 BinValue, SerializationSide, TextValue, Value, ValueDeserializer,
17 },
18};
19use std::{borrow::Cow, fmt, io, marker::PhantomData, ops::Index, sync::Arc};
20
21pub mod convert;
22
23#[derive(Clone, PartialEq)]
29pub struct Row {
30 values: Vec<Option<Value>>,
31 columns: Arc<[Column]>,
32}
33
34impl fmt::Debug for Row {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 let mut debug = f.debug_struct("Row");
37 for (val, column) in self.values.iter().zip(self.columns.iter()) {
38 match *val {
39 Some(ref val) => {
40 debug.field(column.name_str().as_ref(), val);
41 }
42 None => {
43 debug.field(column.name_str().as_ref(), &"<taken>");
44 }
45 }
46 }
47 debug.finish()
48 }
49}
50
51pub fn new_row(values: Vec<Value>, columns: Arc<[Column]>) -> Row {
53 assert!(values.len() == columns.len());
54 Row {
55 values: values.into_iter().map(Some).collect::<Vec<_>>(),
56 columns,
57 }
58}
59
60#[doc(hidden)]
62pub fn new_row_raw(values: Vec<Option<Value>>, columns: Arc<[Column]>) -> Row {
63 assert!(values.len() == columns.len());
64 Row { values, columns }
65}
66
67impl Row {
68 pub fn len(&self) -> usize {
70 self.values.len()
71 }
72
73 pub fn is_empty(&self) -> bool {
75 self.values.is_empty()
76 }
77
78 pub fn columns_ref(&self) -> &[Column] {
80 &self.columns
81 }
82
83 pub fn columns(&self) -> Arc<[Column]> {
85 self.columns.clone()
86 }
87
88 pub fn as_ref(&self, index: usize) -> Option<&Value> {
93 self.values.get(index).and_then(|x| x.as_ref())
94 }
95
96 pub fn get<T, I>(&self, index: I) -> Option<T>
99 where
100 T: FromValue,
101 I: ColumnIndex,
102 {
103 index.idx(&self.columns).and_then(|idx| {
104 self.values
105 .get(idx)
106 .and_then(|x| x.as_ref())
107 .map(|x| from_value::<T>(x.clone()))
108 })
109 }
110
111 pub fn get_opt<T, I>(&self, index: I) -> Option<Result<T, FromValueError>>
115 where
116 T: FromValue,
117 I: ColumnIndex,
118 {
119 index
120 .idx(&self.columns)
121 .and_then(|idx| self.values.get(idx))
122 .and_then(|x| x.as_ref())
123 .map(|x| from_value_opt::<T>(x.clone()))
124 }
125
126 pub fn take<T, I>(&mut self, index: I) -> Option<T>
129 where
130 T: FromValue,
131 I: ColumnIndex,
132 {
133 index.idx(&self.columns).and_then(|idx| {
134 self.values
135 .get_mut(idx)
136 .and_then(|x| x.take())
137 .map(from_value::<T>)
138 })
139 }
140
141 pub fn take_opt<T, I>(&mut self, index: I) -> Option<Result<T, FromValueError>>
145 where
146 T: FromValue,
147 I: ColumnIndex,
148 {
149 index
150 .idx(&self.columns)
151 .and_then(|idx| self.values.get_mut(idx))
152 .and_then(|x| x.take())
153 .map(from_value_opt::<T>)
154 }
155
156 pub fn unwrap(self) -> Vec<Value> {
162 self.values
163 .into_iter()
164 .map(|x| x.expect("Can't unwrap row if some of columns was taken"))
165 .collect()
166 }
167
168 #[doc(hidden)]
170 pub fn unwrap_raw(self) -> Vec<Option<Value>> {
171 self.values
172 }
173
174 #[doc(hidden)]
175 pub fn place(&mut self, index: usize, value: Value) {
176 self.values[index] = Some(value);
177 }
178}
179
180impl Index<usize> for Row {
181 type Output = Value;
182
183 fn index(&self, index: usize) -> &Value {
184 self.values[index].as_ref().unwrap()
185 }
186}
187
188impl<'a> Index<&'a str> for Row {
189 type Output = Value;
190
191 fn index<'r>(&'r self, index: &'a str) -> &'r Value {
192 for (i, column) in self.columns.iter().enumerate() {
193 if column.name_ref() == index.as_bytes() {
194 return self.values[i].as_ref().unwrap();
195 }
196 }
197 panic!("No such column: `{}` in row {:?}", index, self);
198 }
199}
200
201pub trait ColumnIndex {
203 fn idx(&self, columns: &[Column]) -> Option<usize>;
204}
205
206impl ColumnIndex for usize {
207 fn idx(&self, columns: &[Column]) -> Option<usize> {
208 if *self >= columns.len() {
209 None
210 } else {
211 Some(*self)
212 }
213 }
214}
215
216impl ColumnIndex for &'_ str {
217 fn idx(&self, columns: &[Column]) -> Option<usize> {
218 for (i, c) in columns.iter().enumerate() {
219 if c.name_ref() == self.as_bytes() {
220 return Some(i);
221 }
222 }
223 None
224 }
225}
226
227#[derive(Debug, Clone, PartialEq)]
232pub struct RowDeserializer<S, P>(Row, PhantomData<(S, P)>);
233
234impl<S, P> RowDeserializer<S, P> {
235 pub fn into_inner(self) -> Row {
236 self.0
237 }
238}
239
240impl<S, P> From<RowDeserializer<S, P>> for Row {
241 fn from(x: RowDeserializer<S, P>) -> Self {
242 x.0
243 }
244}
245
246impl<'de, T> MyDeserialize<'de> for RowDeserializer<T, Text> {
247 const SIZE: Option<usize> = None;
248 type Ctx = Arc<[Column]>;
249
250 fn deserialize(columns: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
251 let mut values = Vec::with_capacity(columns.len());
252
253 for _ in 0..columns.len() {
254 values.push(Some(
255 ValueDeserializer::<TextValue>::deserialize((), &mut *buf)?.0,
256 ))
257 }
258
259 Ok(Self(Row { values, columns }, PhantomData))
260 }
261}
262
263impl<'de, S: SerializationSide> MyDeserialize<'de> for RowDeserializer<S, Binary> {
264 const SIZE: Option<usize> = None;
265 type Ctx = Arc<[Column]>;
266
267 fn deserialize(columns: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
268 use Value::*;
269
270 buf.checked_eat_u8().ok_or_else(unexpected_buf_eof)?;
271
272 let bitmap = NullBitmap::<S, Cow<'de, [u8]>>::deserialize(columns.len(), &mut *buf)?;
273 let mut values = Vec::with_capacity(columns.len());
274
275 for (i, column) in columns.iter().enumerate() {
276 if bitmap.is_null(i) {
277 values.push(Some(NULL))
278 } else {
279 values.push(Some(
280 ValueDeserializer::<BinValue>::deserialize(
281 (column.column_type(), column.flags()),
282 &mut *buf,
283 )?
284 .0,
285 ));
286 }
287 }
288
289 Ok(Self(Row { values, columns }, PhantomData))
290 }
291}