1use crate::{Row, Value};
4use serde::de::{value::Error as DeError, Error, IntoDeserializer, MapAccess, Visitor};
5use serde::{Deserialize, Deserializer};
6
7struct RowDeserializer<'de> {
8 row: &'de Row,
9}
10
11impl<'de> Deserializer<'de> for RowDeserializer<'de> {
12 type Error = DeError;
13
14 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
15 where
16 V: Visitor<'de>,
17 {
18 Err(DeError::custom("Expects a struct"))
19 }
20
21 fn deserialize_struct<V>(
22 self,
23 _name: &'static str,
24 _fields: &'static [&'static str],
25 visitor: V,
26 ) -> Result<V::Value, Self::Error>
27 where
28 V: Visitor<'de>,
29 {
30 struct RowMapAccess<'a> {
31 row: &'a Row,
32 idx: std::ops::Range<usize>,
33 value: Option<Value>,
34 }
35
36 impl<'de> MapAccess<'de> for RowMapAccess<'de> {
37 type Error = DeError;
38
39 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
40 where
41 K: serde::de::DeserializeSeed<'de>,
42 {
43 match self.idx.next() {
44 None => Ok(None),
45 Some(i) => {
46 let value = self.row.get_value(i as i32).map_err(DeError::custom)?;
47 self.value = Some(value);
48 self.row
49 .column_name(i as i32)
50 .map(|name| seed.deserialize(name.into_deserializer()))
51 .transpose()
52 }
53 }
54 }
55
56 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
57 where
58 V: serde::de::DeserializeSeed<'de>,
59 {
60 let value = self
61 .value
62 .take()
63 .ok_or(DeError::custom("Expects a value but row is exhausted"))?;
64
65 seed.deserialize(value.into_deserializer())
66 }
67 }
68
69 visitor.visit_map(RowMapAccess {
70 row: self.row,
71 idx: 0..(self.row.inner.column_count() as usize),
72 value: None,
73 })
74 }
75
76 serde::forward_to_deserialize_any! {
77 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
78 bytes byte_buf option unit unit_struct newtype_struct seq tuple
79 tuple_struct map enum identifier ignored_any
80 }
81}
82
83pub fn from_row<'de, T: Deserialize<'de>>(row: &'de Row) -> Result<T, DeError> {
84 let de = RowDeserializer { row };
85 T::deserialize(de)
86}