summa_core/components/
custom_serializer.rs

1use std::collections::{BTreeMap, HashSet};
2
3use serde::{Serialize, Serializer};
4use tantivy::schema::{Field, OwnedValue, Schema, Value as ValueTrait};
5use tantivy::{Document, TantivyDocument};
6
7/// `Value` is used for representing singular or multi-values of `tantivy::Document`
8///
9/// Required because Tantivy operates with multi-values only and Summa provides an abstraction of singular fields
10pub enum Value {
11    SingleValue(Option<OwnedValue>),
12    MultipleValue(Vec<OwnedValue>),
13}
14
15/// Internal representation of a document used for JSON
16/// serialization.
17///
18/// A `NamedFieldDocument` is a simple representation of a document
19/// as a `BTreeMap<String, Vec<Value>>`. It is base on `tantivy::schema::NamedFieldDocument`
20/// but with a support of multi fields
21#[derive(Serialize)]
22pub struct NamedFieldDocument<'a>(pub BTreeMap<&'a str, Value>);
23
24impl<'a> NamedFieldDocument<'a> {
25    pub fn from_document(schema: &'a Schema, fields: &Option<HashSet<Field>>, multi_fields: &HashSet<Field>, document: &'a TantivyDocument) -> Self {
26        let mut field_map = BTreeMap::new();
27        for (field, field_values) in document.get_sorted_field_values() {
28            let field_name = schema.get_field_name(field);
29            if let Some(fields) = fields {
30                if !fields.contains(&field) {
31                    continue;
32                }
33            }
34            let values = if multi_fields.contains(&field) {
35                Value::MultipleValue(field_values.into_iter().map(|x| OwnedValue::from(x.as_value())).collect())
36            } else {
37                Value::SingleValue(field_values.get(0).map(|x| OwnedValue::from(x.as_value())))
38            };
39            field_map.insert(field_name, values);
40        }
41        NamedFieldDocument(field_map)
42    }
43    pub fn to_json_string(&self) -> String {
44        serde_json::to_string(self).expect("must be serializable")
45    }
46}
47
48impl Serialize for Value {
49    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
50    where
51        S: Serializer,
52    {
53        match self {
54            Value::SingleValue(value) => value.serialize(serializer),
55            Value::MultipleValue(value) => value.serialize(serializer),
56        }
57    }
58}