tantivy/query/
explanation.rs

1use std::borrow::Cow;
2use std::fmt;
3
4use serde::Serialize;
5
6use crate::{DocId, Score, TantivyError};
7
8pub(crate) fn does_not_match(doc: DocId) -> TantivyError {
9    TantivyError::InvalidArgument(format!("Document #({doc}) does not match"))
10}
11
12/// Object describing the score of a given document.
13/// It is organized in trees.
14///
15/// `.to_pretty_json()` can be useful to print out a human readable
16/// representation of this tree when debugging a given score.
17#[derive(Clone, Serialize)]
18pub struct Explanation {
19    value: Score,
20    description: Cow<'static, str>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    details: Option<Vec<Explanation>>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    context: Option<Vec<String>>,
25}
26impl fmt::Debug for Explanation {
27    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28        write!(f, "Explanation({})", self.to_pretty_json())
29    }
30}
31
32impl Explanation {
33    /// Creates a new explanation object.
34    pub fn new_with_string(description: String, value: Score) -> Explanation {
35        Explanation {
36            value,
37            description: Cow::Owned(description),
38            details: None,
39            context: None,
40        }
41    }
42    /// Creates a new explanation object.
43    pub fn new(description: &'static str, value: Score) -> Explanation {
44        Explanation {
45            value,
46            description: Cow::Borrowed(description),
47            details: None,
48            context: None,
49        }
50    }
51
52    /// Returns the value associated with the current node.
53    pub fn value(&self) -> Score {
54        self.value
55    }
56
57    /// Add some detail, explaining some part of the current node formula.
58    ///
59    /// Details are treated as child of the current node.
60    pub fn add_detail(&mut self, child_explanation: Explanation) {
61        self.details
62            .get_or_insert_with(Vec::new)
63            .push(child_explanation);
64    }
65
66    /// Adds some extra context to the explanation.
67    pub fn add_context(&mut self, context: String) {
68        self.context.get_or_insert_with(Vec::new).push(context);
69    }
70
71    /// Shortcut for `self.details.push(Explanation::new(name, value));`
72    pub fn add_const(&mut self, name: &'static str, value: Score) {
73        self.details
74            .get_or_insert_with(Vec::new)
75            .push(Explanation::new(name, value));
76    }
77
78    /// Returns an indented json representation of the explanation tree for debug usage.
79    pub fn to_pretty_json(&self) -> String {
80        serde_json::to_string_pretty(self).unwrap()
81    }
82}