elasticsearch_dsl/search/response/
source.rs

1use crate::util::ShouldSkip;
2use serde::de::DeserializeOwned;
3use serde_json::{value::RawValue, Value};
4
5/// Document source with delayed deserialization
6#[derive(Clone, Default, Serialize, Deserialize)]
7pub struct Source(Box<RawValue>);
8
9impl std::fmt::Debug for Source {
10    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11        self.0.fmt(f)
12    }
13}
14
15impl std::fmt::Display for Source {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        self.0.fmt(f)
18    }
19}
20
21impl PartialEq for Source {
22    fn eq(&self, other: &Self) -> bool {
23        self.0.get() == other.0.get()
24    }
25}
26
27impl ShouldSkip for Source {
28    fn should_skip(&self) -> bool {
29        self.eq(&Source::default())
30    }
31}
32
33impl Source {
34    /// Parses document source into a concrete type
35    pub fn parse<T>(&self) -> Result<T, serde_json::Error>
36    where
37        T: DeserializeOwned,
38    {
39        serde_json::from_str(self.0.get())
40    }
41
42    /// Creates source from a string
43    pub fn from_string(value: String) -> Result<Self, serde_json::Error> {
44        RawValue::from_string(value).map(Self)
45    }
46}
47
48impl From<Value> for Source {
49    /// Creates source from a [Value]
50    ///
51    /// Calling expect here because [Value] always represents a valid JSON and it
52    /// _should be safe_ to do so.
53    fn from(value: Value) -> Self {
54        Self(RawValue::from_string(format!("{value}")).expect("valid json"))
55    }
56}
57
58impl From<Box<RawValue>> for Source {
59    fn from(value: Box<RawValue>) -> Self {
60        Self(value)
61    }
62}
63
64impl<'a> From<&'a RawValue> for Source {
65    fn from(value: &'a RawValue) -> Self {
66        Self(value.to_owned())
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn creates_from_json_value() {
76        let _ = Source::from(json!({"key": "value"}));
77        let _ = Source::from(json!({"key": ["value", 1, 1.2, true, null, {"key2": "value2"}]}));
78        let _ = Source::from(json!(["one", 2, 3.0, false, null, {}]));
79    }
80}