serde_arrow 0.14.0

Convert sequences of Rust objects to Arrow arrays and back again
Documentation
use marrow::view::{BytesView, PrimitiveView};
use serde::de::Visitor;

use crate::internal::{
    error::{set_default, try_, Context, ContextSupport, Error, ErrorKind, Result},
    utils::{array_view_ext::ViewAccess, Offset},
};

use super::{
    enums_as_string_impl::EnumAccess, integer_deserializer::Integer,
    random_access_deserializer::RandomAccessDeserializer, utils::bitset_all_set,
};

pub struct DictionaryDeserializer<'a, K: Integer, V: Offset> {
    path: String,
    keys: PrimitiveView<'a, K>,
    values: BytesView<'a, V>,
}

impl<'a, K: Integer, V: Offset> DictionaryDeserializer<'a, K, V> {
    pub fn new(path: String, keys: PrimitiveView<'a, K>, values: BytesView<'a, V>) -> Result<Self> {
        if let Some(validity) = &values.validity {
            if !bitset_all_set(validity, values.offsets.len() - 1)? {
                return Err(Error::new(
                    ErrorKind::NullabilityViolation { field: None },
                    "Null for non-nullable type: dictionaries do not support nullable values"
                        .into(),
                ));
            }
        }
        Ok(Self {
            path,
            keys: keys.clone(),
            values: values.clone(),
        })
    }

    pub fn get_str(&self, idx: usize) -> Result<&str> {
        let key: usize = self.keys.get_required(idx)?.into_i64()?.try_into()?;
        let value: &str = self.values.get_required(key)?;
        Ok(value)
    }
}

impl<K: Integer, V: Offset> Context for DictionaryDeserializer<'_, K, V> {
    fn annotate(&self, annotations: &mut std::collections::BTreeMap<String, String>) {
        set_default(annotations, "field", &self.path);
        set_default(annotations, "data_type", "Dictionary");
    }
}

impl<'de, K: Integer, V: Offset> RandomAccessDeserializer<'de>
    for DictionaryDeserializer<'de, K, V>
{
    fn is_some(&self, idx: usize) -> Result<bool> {
        self.keys.is_some(idx)
    }

    fn deserialize_any_some<VV: Visitor<'de>>(&self, visitor: VV, idx: usize) -> Result<VV::Value> {
        self.deserialize_str(visitor, idx)
    }

    fn deserialize_str<VV: Visitor<'de>>(&self, visitor: VV, idx: usize) -> Result<VV::Value> {
        try_(|| visitor.visit_str(self.get_str(idx)?)).ctx(self)
    }

    fn deserialize_string<VV: Visitor<'de>>(&self, visitor: VV, idx: usize) -> Result<VV::Value> {
        try_(|| visitor.visit_string(self.get_str(idx)?.to_owned())).ctx(self)
    }

    fn deserialize_enum<VV: Visitor<'de>>(
        &self,
        _: &'static str,
        _: &'static [&'static str],
        visitor: VV,
        idx: usize,
    ) -> Result<VV::Value> {
        try_(|| visitor.visit_enum(EnumAccess(self.get_str(idx)?))).ctx(self)
    }
}