use meilisearch_schema::{Schema, SchemaAttr, SchemaProps}; use serde::ser; use crate::raw_indexer::RawIndexer; use crate::store::{DocumentsFields, DocumentsFieldsCounts}; use crate::{DocumentId, RankedMap}; use super::{ConvertToNumber, ConvertToString, Indexer, SerializerError}; pub struct Serializer<'a, 'b> { pub txn: &'a mut heed::RwTxn<'b>, pub schema: &'a Schema, pub document_store: DocumentsFields, pub document_fields_counts: DocumentsFieldsCounts, pub indexer: &'a mut RawIndexer, pub ranked_map: &'a mut RankedMap, pub document_id: DocumentId, } impl<'a, 'b> ser::Serializer for Serializer<'a, 'b> { type Ok = (); type Error = SerializerError; type SerializeSeq = ser::Impossible; type SerializeTuple = ser::Impossible; type SerializeTupleStruct = ser::Impossible; type SerializeTupleVariant = ser::Impossible; type SerializeMap = MapSerializer<'a, 'b>; type SerializeStruct = StructSerializer<'a, 'b>; type SerializeStructVariant = ser::Impossible; forward_to_unserializable_type! { bool => serialize_bool, char => serialize_char, i8 => serialize_i8, i16 => serialize_i16, i32 => serialize_i32, i64 => serialize_i64, u8 => serialize_u8, u16 => serialize_u16, u32 => serialize_u32, u64 => serialize_u64, f32 => serialize_f32, f64 => serialize_f64, } fn serialize_str(self, _v: &str) -> Result { Err(SerializerError::UnserializableType { type_name: "str" }) } fn serialize_bytes(self, _v: &[u8]) -> Result { Err(SerializerError::UnserializableType { type_name: "&[u8]" }) } fn serialize_none(self) -> Result { Err(SerializerError::UnserializableType { type_name: "Option", }) } fn serialize_some(self, _value: &T) -> Result where T: ser::Serialize, { Err(SerializerError::UnserializableType { type_name: "Option", }) } fn serialize_unit(self) -> Result { Err(SerializerError::UnserializableType { type_name: "()" }) } fn serialize_unit_struct(self, _name: &'static str) -> Result { Err(SerializerError::UnserializableType { type_name: "unit struct", }) } fn serialize_unit_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, ) -> Result { Err(SerializerError::UnserializableType { type_name: "unit variant", }) } fn serialize_newtype_struct( self, _name: &'static str, value: &T, ) -> Result where T: ser::Serialize, { value.serialize(self) } fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T, ) -> Result where T: ser::Serialize, { Err(SerializerError::UnserializableType { type_name: "newtype variant", }) } fn serialize_seq(self, _len: Option) -> Result { Err(SerializerError::UnserializableType { type_name: "sequence", }) } fn serialize_tuple(self, _len: usize) -> Result { Err(SerializerError::UnserializableType { type_name: "tuple" }) } fn serialize_tuple_struct( self, _name: &'static str, _len: usize, ) -> Result { Err(SerializerError::UnserializableType { type_name: "tuple struct", }) } fn serialize_tuple_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize, ) -> Result { Err(SerializerError::UnserializableType { type_name: "tuple variant", }) } fn serialize_map(self, _len: Option) -> Result { Ok(MapSerializer { txn: self.txn, schema: self.schema, document_id: self.document_id, document_store: self.document_store, document_fields_counts: self.document_fields_counts, indexer: self.indexer, ranked_map: self.ranked_map, current_key_name: None, }) } fn serialize_struct( self, _name: &'static str, _len: usize, ) -> Result { Ok(StructSerializer { txn: self.txn, schema: self.schema, document_id: self.document_id, document_store: self.document_store, document_fields_counts: self.document_fields_counts, indexer: self.indexer, ranked_map: self.ranked_map, }) } fn serialize_struct_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize, ) -> Result { Err(SerializerError::UnserializableType { type_name: "struct variant", }) } } pub struct MapSerializer<'a, 'b> { txn: &'a mut heed::RwTxn<'b>, schema: &'a Schema, document_id: DocumentId, document_store: DocumentsFields, document_fields_counts: DocumentsFieldsCounts, indexer: &'a mut RawIndexer, ranked_map: &'a mut RankedMap, current_key_name: Option, } impl<'a, 'b> ser::SerializeMap for MapSerializer<'a, 'b> { type Ok = (); type Error = SerializerError; fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where T: ser::Serialize, { let key = key.serialize(ConvertToString)?; self.current_key_name = Some(key); Ok(()) } fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> where T: ser::Serialize, { let key = self.current_key_name.take().unwrap(); self.serialize_entry(&key, value) } fn serialize_entry( &mut self, key: &K, value: &V, ) -> Result<(), Self::Error> where K: ser::Serialize, V: ser::Serialize, { let key = key.serialize(ConvertToString)?; match self.schema.attribute(&key) { Some(attribute) => serialize_value( self.txn, attribute, self.schema.props(attribute), self.document_id, self.document_store, self.document_fields_counts, self.indexer, self.ranked_map, value, ), None => Ok(()), } } fn end(self) -> Result { Ok(()) } } pub struct StructSerializer<'a, 'b> { txn: &'a mut heed::RwTxn<'b>, schema: &'a Schema, document_id: DocumentId, document_store: DocumentsFields, document_fields_counts: DocumentsFieldsCounts, indexer: &'a mut RawIndexer, ranked_map: &'a mut RankedMap, } impl<'a, 'b> ser::SerializeStruct for StructSerializer<'a, 'b> { type Ok = (); type Error = SerializerError; fn serialize_field( &mut self, key: &'static str, value: &T, ) -> Result<(), Self::Error> where T: ser::Serialize, { match self.schema.attribute(key) { Some(attribute) => serialize_value( self.txn, attribute, self.schema.props(attribute), self.document_id, self.document_store, self.document_fields_counts, self.indexer, self.ranked_map, value, ), None => Ok(()), } } fn end(self) -> Result { Ok(()) } } pub fn serialize_value( txn: &mut heed::RwTxn, attribute: SchemaAttr, props: SchemaProps, document_id: DocumentId, document_store: DocumentsFields, documents_fields_counts: DocumentsFieldsCounts, indexer: &mut RawIndexer, ranked_map: &mut RankedMap, value: &T, ) -> Result<(), SerializerError> where T: ser::Serialize, { let serialized = serde_json::to_vec(value)?; document_store.put_document_field(txn, document_id, attribute, &serialized)?; if props.is_indexed() { let indexer = Indexer { attribute, indexer, document_id, }; if let Some(number_of_words) = value.serialize(indexer)? { documents_fields_counts.put_document_field_count( txn, document_id, attribute, number_of_words as u64, )?; } } if props.is_ranked() { let number = value.serialize(ConvertToNumber)?; ranked_map.insert(document_id, attribute, number); } Ok(()) }