Skip to main content

ctl_core/
format.rs

1use std::fmt;
2use std::str::FromStr;
3
4/// Hosts `JsonSchema`. schemars expands `concat!`; this module is the allow.
5mod data {
6    #![expect(
7        clippy::disallowed_macros,
8        reason = "schemars' JsonSchema derive expands concat!"
9    )]
10
11    /// Output representation. Models serialize first; views pick one of these.
12    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
13    #[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
14    #[cfg_attr(feature = "json", derive(serde::Deserialize, serde::Serialize))]
15    #[cfg_attr(feature = "json", serde(rename_all = "lowercase"))]
16    #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
17    pub enum OutputFormat {
18        #[default]
19        /// Human text, optionally colored.
20        Pretty,
21        /// Machine JSON. Never contains ANSI.
22        Json,
23    }
24}
25
26pub use data::OutputFormat;
27
28impl OutputFormat {
29    #[must_use]
30    /// `true` when this view is JSON.
31    pub fn is_json(self) -> bool {
32        self == Self::Json
33    }
34}
35
36impl FromStr for OutputFormat {
37    type Err = ParseFormatError;
38
39    fn from_str(value: &str) -> Result<Self, Self::Err> {
40        match value {
41            "pretty" => Ok(Self::Pretty),
42            "json" => Ok(Self::Json),
43            _ => Err(ParseFormatError),
44        }
45    }
46}
47
48impl fmt::Display for OutputFormat {
49    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50        f.write_str(match self {
51            Self::Pretty => "pretty",
52            Self::Json => "json",
53        })
54    }
55}
56
57#[derive(Clone, Copy, Debug, Eq, PartialEq)]
58/// Unknown format token.
59pub struct ParseFormatError;
60
61impl fmt::Display for ParseFormatError {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        f.write_str("expected pretty or json")
64    }
65}
66
67impl std::error::Error for ParseFormatError {}
68
69#[cfg(test)]
70mod tests {
71    use super::OutputFormat;
72
73    #[test]
74    fn json_predicate() {
75        assert!(OutputFormat::Json.is_json());
76        assert!(!OutputFormat::Pretty.is_json());
77        assert_eq!("json".parse::<OutputFormat>().unwrap(), OutputFormat::Json);
78    }
79}