use std::borrow::Cow;
use std::fmt;
use serde::Serialize;
use crate::{DocId, Score, LucivyError};
pub(crate) fn does_not_match(doc: DocId) -> LucivyError {
LucivyError::InvalidArgument(format!("Document #({doc}) does not match"))
}
#[derive(Clone, Serialize)]
pub struct Explanation {
value: Score,
description: Cow<'static, str>,
#[serde(skip_serializing_if = "Option::is_none")]
details: Option<Vec<Explanation>>,
#[serde(skip_serializing_if = "Option::is_none")]
context: Option<Vec<String>>,
}
impl fmt::Debug for Explanation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Explanation({})", self.to_pretty_json())
}
}
impl Explanation {
pub fn new_with_string(description: String, value: Score) -> Explanation {
Explanation {
value,
description: Cow::Owned(description),
details: None,
context: None,
}
}
pub fn new(description: &'static str, value: Score) -> Explanation {
Explanation {
value,
description: Cow::Borrowed(description),
details: None,
context: None,
}
}
pub fn value(&self) -> Score {
self.value
}
pub fn add_detail(&mut self, child_explanation: Explanation) {
self.details
.get_or_insert_with(Vec::new)
.push(child_explanation);
}
pub fn add_context(&mut self, context: String) {
self.context.get_or_insert_with(Vec::new).push(context);
}
pub fn add_const(&mut self, name: &'static str, value: Score) {
self.details
.get_or_insert_with(Vec::new)
.push(Explanation::new(name, value));
}
pub fn to_pretty_json(&self) -> String {
serde_json::to_string_pretty(self).unwrap()
}
}