libsql 0.5.0

libSQL library: the main gateway for interacting with the database
Documentation
//! Deserialization utilities.

use crate::{Row, Value};
use serde::de::{value::Error as DeError, Error, IntoDeserializer, MapAccess, Visitor};
use serde::{Deserialize, Deserializer};

struct RowDeserializer<'de> {
    row: &'de Row,
}

impl<'de> Deserializer<'de> for RowDeserializer<'de> {
    type Error = DeError;

    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        Err(DeError::custom("Expects a struct"))
    }

    fn deserialize_struct<V>(
        self,
        _name: &'static str,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        struct RowMapAccess<'a> {
            row: &'a Row,
            idx: std::ops::Range<usize>,
            value: Option<Value>,
        }

        impl<'de> MapAccess<'de> for RowMapAccess<'de> {
            type Error = DeError;

            fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
            where
                K: serde::de::DeserializeSeed<'de>,
            {
                match self.idx.next() {
                    None => Ok(None),
                    Some(i) => {
                        let value = self.row.get_value(i as i32).map_err(DeError::custom)?;
                        self.value = Some(value);
                        self.row
                            .column_name(i as i32)
                            .map(|name| seed.deserialize(name.into_deserializer()))
                            .transpose()
                    }
                }
            }

            fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
            where
                V: serde::de::DeserializeSeed<'de>,
            {
                let value = self
                    .value
                    .take()
                    .ok_or(DeError::custom("Expects a value but row is exhausted"))?;

                seed.deserialize(value.into_deserializer())
            }
        }

        visitor.visit_map(RowMapAccess {
            row: self.row,
            idx: 0..self.row.inner.column_count(),
            value: None,
        })
    }

    serde::forward_to_deserialize_any! {
        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
        bytes byte_buf option unit unit_struct newtype_struct seq tuple
        tuple_struct map enum identifier ignored_any
    }
}

pub fn from_row<'de, T: Deserialize<'de>>(row: &'de Row) -> Result<T, DeError> {
    let de = RowDeserializer { row };
    T::deserialize(de)
}