1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! A library for creating structured output for command line applications.
//!
//!
//! # Example
//!
//! ```
//! use structured_output::StructuredOutput;
//!
//! let lines = "Hello world!";
//! let json = serde_json::json!({ "message": lines });
//! let output = StructuredOutput::new(lines, json.clone());
//! assert_eq!(output.lines(), "Hello world!");
//! assert_eq!(output.json(), &json);
//! ```
//!

#[derive(Debug, Default, Clone, PartialEq)]
/// A struct that contains both a string and a json value.
pub struct StructuredOutput {
    pub lines: String,
    pub json: serde_json::Value,
}

impl StructuredOutput {
    /// Create a new [StructuredOutput] that includes both a string and a json value.
    ///
    pub fn new(lines: impl Into<String>, json: impl Into<serde_json::Value>) -> StructuredOutput {
        StructuredOutput {
            lines: lines.into(),
            json: json.into(),
        }
    }

    /// Get the string value of the output.
    ///
    pub fn lines(&self) -> &str {
        &self.lines
    }

    /// Get the json value of the output.
    pub fn json(&self) -> &serde_json::Value {
        &self.json
    }

    /// Get the json value of the output as a JSON string.
    pub fn to_json_string(&self) -> String {
        serde_json::to_string(&self.json).unwrap()
    }

    /// Get the json value of the output as a prettified JSON string.
    pub fn to_json_pretty(&self) -> String {
        serde_json::to_string_pretty(&self.json).unwrap()
    }
}

impl std::fmt::Display for StructuredOutput {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.lines)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let lines = "Hello world!";
        let json = serde_json::json!({ "message": lines });
        let output = StructuredOutput::new(lines, json.clone());
        assert_eq!(output.lines(), "Hello world!");
        assert_eq!(output.json(), &json);
    }
}