2019-10-03 11:49:13 +02:00
|
|
|
use std::collections::HashSet;
|
|
|
|
use std::io::Cursor;
|
2019-10-18 13:05:28 +02:00
|
|
|
use std::{error::Error, fmt};
|
2019-10-03 11:49:13 +02:00
|
|
|
|
2020-01-10 18:20:30 +01:00
|
|
|
use meilisearch_schema::{Schema, FieldId};
|
2019-10-03 11:49:13 +02:00
|
|
|
use serde::{de, forward_to_deserialize_any};
|
2019-10-18 13:05:28 +02:00
|
|
|
use serde_json::de::IoRead as SerdeJsonIoRead;
|
|
|
|
use serde_json::Deserializer as SerdeJsonDeserializer;
|
|
|
|
use serde_json::Error as SerdeJsonError;
|
2019-10-03 11:49:13 +02:00
|
|
|
|
2019-11-26 16:12:06 +01:00
|
|
|
use crate::database::MainT;
|
2019-10-03 11:49:13 +02:00
|
|
|
use crate::store::DocumentsFields;
|
|
|
|
use crate::DocumentId;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum DeserializerError {
|
2019-10-11 16:16:21 +02:00
|
|
|
SerdeJson(SerdeJsonError),
|
2019-10-21 12:05:53 +02:00
|
|
|
Zlmdb(heed::Error),
|
2019-10-03 11:49:13 +02:00
|
|
|
Custom(String),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl de::Error for DeserializerError {
|
|
|
|
fn custom<T: fmt::Display>(msg: T) -> Self {
|
|
|
|
DeserializerError::Custom(msg.to_string())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for DeserializerError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
2019-10-11 16:16:21 +02:00
|
|
|
DeserializerError::SerdeJson(e) => write!(f, "serde json related error: {}", e),
|
2019-10-21 12:05:53 +02:00
|
|
|
DeserializerError::Zlmdb(e) => write!(f, "heed related error: {}", e),
|
2019-10-03 11:49:13 +02:00
|
|
|
DeserializerError::Custom(s) => f.write_str(s),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error for DeserializerError {}
|
|
|
|
|
2019-10-11 16:16:21 +02:00
|
|
|
impl From<SerdeJsonError> for DeserializerError {
|
|
|
|
fn from(error: SerdeJsonError) -> DeserializerError {
|
|
|
|
DeserializerError::SerdeJson(error)
|
2019-10-03 11:49:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-21 12:05:53 +02:00
|
|
|
impl From<heed::Error> for DeserializerError {
|
|
|
|
fn from(error: heed::Error) -> DeserializerError {
|
2019-10-16 17:05:24 +02:00
|
|
|
DeserializerError::Zlmdb(error)
|
2019-10-03 11:49:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-16 17:05:24 +02:00
|
|
|
pub struct Deserializer<'a> {
|
2019-10-03 11:49:13 +02:00
|
|
|
pub document_id: DocumentId,
|
2019-11-26 16:12:06 +01:00
|
|
|
pub reader: &'a heed::RoTxn<MainT>,
|
2019-10-03 11:49:13 +02:00
|
|
|
pub documents_fields: DocumentsFields,
|
|
|
|
pub schema: &'a Schema,
|
2020-01-29 18:30:21 +01:00
|
|
|
pub fields: Option<&'a HashSet<FieldId>>,
|
2019-10-03 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2019-10-16 17:05:24 +02:00
|
|
|
impl<'de, 'a, 'b> de::Deserializer<'de> for &'b mut Deserializer<'a> {
|
2019-10-03 11:49:13 +02:00
|
|
|
type Error = DeserializerError;
|
|
|
|
|
|
|
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
2019-10-18 13:05:28 +02:00
|
|
|
where
|
|
|
|
V: de::Visitor<'de>,
|
2019-10-03 11:49:13 +02:00
|
|
|
{
|
2019-11-05 15:03:18 +01:00
|
|
|
self.deserialize_option(visitor)
|
2019-10-03 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2019-11-05 15:03:18 +01:00
|
|
|
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
|
|
where
|
|
|
|
V: de::Visitor<'de>,
|
|
|
|
{
|
|
|
|
self.deserialize_map(visitor)
|
2019-10-03 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
2019-10-18 13:05:28 +02:00
|
|
|
where
|
|
|
|
V: de::Visitor<'de>,
|
2019-10-03 11:49:13 +02:00
|
|
|
{
|
|
|
|
let mut error = None;
|
|
|
|
|
2019-10-18 13:05:28 +02:00
|
|
|
let iter = self
|
|
|
|
.documents_fields
|
2019-10-03 11:49:13 +02:00
|
|
|
.document_fields(self.reader, self.document_id)?
|
|
|
|
.filter_map(|result| {
|
|
|
|
let (attr, value) = match result {
|
|
|
|
Ok(value) => value,
|
2019-10-18 13:05:28 +02:00
|
|
|
Err(e) => {
|
|
|
|
error = Some(e);
|
|
|
|
return None;
|
|
|
|
}
|
2019-10-03 11:49:13 +02:00
|
|
|
};
|
|
|
|
|
2020-01-29 18:30:21 +01:00
|
|
|
let is_displayed = self.schema.is_displayed(attr);
|
|
|
|
if is_displayed && self.fields.map_or(true, |f| f.contains(&attr)) {
|
|
|
|
if let Some(attribute_name) = self.schema.name(attr) {
|
2020-01-10 18:20:30 +01:00
|
|
|
let cursor = Cursor::new(value.to_owned());
|
|
|
|
let ioread = SerdeJsonIoRead::new(cursor);
|
|
|
|
let value = Value(SerdeJsonDeserializer::new(ioread));
|
|
|
|
|
2020-01-13 19:10:58 +01:00
|
|
|
Some((attribute_name, value))
|
2020-01-10 18:20:30 +01:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2019-10-03 11:49:13 +02:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2019-11-05 15:03:18 +01:00
|
|
|
let mut iter = iter.peekable();
|
|
|
|
|
|
|
|
let result = match iter.peek() {
|
|
|
|
Some(_) => {
|
|
|
|
let map_deserializer = de::value::MapDeserializer::new(iter);
|
|
|
|
visitor
|
|
|
|
.visit_some(map_deserializer)
|
|
|
|
.map_err(DeserializerError::from)
|
|
|
|
}
|
|
|
|
None => visitor.visit_none(),
|
|
|
|
};
|
2019-10-03 11:49:13 +02:00
|
|
|
|
|
|
|
match error.take() {
|
|
|
|
Some(error) => Err(error.into()),
|
|
|
|
None => result,
|
|
|
|
}
|
|
|
|
}
|
2019-11-05 15:03:18 +01:00
|
|
|
|
|
|
|
forward_to_deserialize_any! {
|
|
|
|
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
|
|
|
bytes byte_buf unit unit_struct newtype_struct seq tuple
|
|
|
|
tuple_struct struct enum identifier ignored_any
|
|
|
|
}
|
2019-10-03 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2019-10-11 16:16:21 +02:00
|
|
|
struct Value(SerdeJsonDeserializer<SerdeJsonIoRead<Cursor<Vec<u8>>>>);
|
2019-10-03 11:49:13 +02:00
|
|
|
|
2019-10-11 16:16:21 +02:00
|
|
|
impl<'de> de::IntoDeserializer<'de, SerdeJsonError> for Value {
|
2019-10-03 11:49:13 +02:00
|
|
|
type Deserializer = Self;
|
|
|
|
|
|
|
|
fn into_deserializer(self) -> Self::Deserializer {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-11 16:16:21 +02:00
|
|
|
impl<'de> de::Deserializer<'de> for Value {
|
|
|
|
type Error = SerdeJsonError;
|
2019-10-03 11:49:13 +02:00
|
|
|
|
|
|
|
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
2019-10-18 13:05:28 +02:00
|
|
|
where
|
|
|
|
V: de::Visitor<'de>,
|
2019-10-03 11:49:13 +02:00
|
|
|
{
|
|
|
|
self.0.deserialize_any(visitor)
|
|
|
|
}
|
|
|
|
|
|
|
|
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 struct enum identifier ignored_any
|
|
|
|
}
|
|
|
|
}
|