1use std::fmt;
16use std::str::FromStr;
17
18mod data {
21 #![cfg_attr(
22 feature = "schema",
23 expect(
24 clippy::disallowed_macros,
25 reason = "schemars' JsonSchema derive expands concat!"
26 )
27 )]
28
29 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
34 #[non_exhaustive]
35 #[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
36 #[cfg_attr(feature = "json", derive(serde::Deserialize, serde::Serialize))]
37 #[cfg_attr(feature = "json", serde(rename_all = "lowercase"))]
38 #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
39 pub enum OutputFormat {
40 #[default]
41 Pretty,
43 Json,
45 }
46}
47
48pub use data::OutputFormat;
49
50impl OutputFormat {
51 #[must_use]
52 pub fn is_json(self) -> bool {
54 self == Self::Json
55 }
56}
57
58impl FromStr for OutputFormat {
59 type Err = ParseFormatError;
60
61 fn from_str(value: &str) -> Result<Self, Self::Err> {
62 match value {
63 "pretty" => Ok(Self::Pretty),
64 "json" => Ok(Self::Json),
65 _ => Err(ParseFormatError),
66 }
67 }
68}
69
70impl fmt::Display for OutputFormat {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 f.write_str(match self {
73 Self::Pretty => "pretty",
74 Self::Json => "json",
75 })
76 }
77}
78
79#[derive(Clone, Copy, Debug, Eq, PartialEq)]
80pub struct ParseFormatError;
83
84impl fmt::Display for ParseFormatError {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 f.write_str("expected pretty or json")
87 }
88}
89
90impl std::error::Error for ParseFormatError {}
91
92#[cfg(test)]
93mod tests {
94 use super::OutputFormat;
95
96 #[test]
97 fn json_predicate() {
98 assert!(OutputFormat::Json.is_json());
99 assert!(!OutputFormat::Pretty.is_json());
100 assert_eq!("json".parse::<OutputFormat>().unwrap(), OutputFormat::Json);
101 }
102}