1use std::io::Write;
2use std::str::FromStr;
3
4use crate::output::console::ConsoleOutput;
5use crate::output::json::JsonOutput;
6use crate::output::yaml::YamlOutput;
7use anyhow::Result;
8use serde::{Deserialize, Serialize};
9
10pub mod console;
11pub mod json;
12pub mod yaml;
13
14#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
15pub enum OutputFormat {
16 Console,
17 Yaml,
18 Json,
19}
20
21pub trait OutputTrait {
22 fn display<'a, T: Deserialize<'a> + Serialize>(
23 &self,
24 writer: impl Write,
25 obj: &T,
26 include_keys: Option<Vec<&str>>,
27 exclude_keys: Option<Vec<&str>>,
28 ) -> Result<()>;
29}
30
31impl FromStr for OutputFormat {
32 type Err = String;
33
34 fn from_str(s: &str) -> Result<Self, Self::Err> {
35 match s.to_lowercase().as_str() {
36 "console" => Ok(OutputFormat::Console),
37 "json" => Ok(OutputFormat::Json),
38 "yaml" => Ok(OutputFormat::Yaml),
39 _ => Err(format!("{} not supported format", s)),
40 }
41 }
42}
43
44pub struct OutputFactory {
45 pub output: OutputFormat,
46}
47
48impl OutputFactory {
49 pub fn new(output: OutputFormat) -> Self {
50 Self { output }
51 }
52}
53
54impl OutputTrait for OutputFactory {
55 fn display<'a, T: Deserialize<'a> + Serialize>(
56 &self,
57 writer: impl Write,
58 obj: &T,
59 include_keys: Option<Vec<&str>>,
60 exclude_keys: Option<Vec<&str>>,
61 ) -> Result<()> {
62 match self.output {
63 OutputFormat::Console => {
64 ConsoleOutput::new().display(writer, obj, include_keys, exclude_keys)
65 }
66
67 OutputFormat::Yaml => {
68 YamlOutput::new().display(writer, obj, include_keys, exclude_keys)
69 }
70
71 OutputFormat::Json => {
72 JsonOutput::new().display(writer, obj, include_keys, exclude_keys)
73 }
74 }
75 }
76}