dotenv_analyzer/
lint_kind.rs

1use std::{fmt, str::FromStr};
2
3#[derive(Debug, PartialEq, Eq, Clone, Copy)]
4pub enum LintKind {
5    DuplicatedKey,
6    EndingBlankLine,
7    ExtraBlankLine,
8    IncorrectDelimiter,
9    KeyWithoutValue,
10    LeadingCharacter,
11    LowercaseKey,
12    QuoteCharacter,
13    SpaceCharacter,
14    SubstitutionKey,
15    TrailingWhitespace,
16    UnorderedKey,
17    ValueWithoutQuotes,
18    SchemaViolation,
19}
20
21impl FromStr for LintKind {
22    type Err = ();
23
24    fn from_str(s: &str) -> Result<Self, Self::Err> {
25        match s {
26            "DuplicatedKey" => Ok(LintKind::DuplicatedKey),
27            "EndingBlankLine" => Ok(LintKind::EndingBlankLine),
28            "ExtraBlankLine" => Ok(LintKind::ExtraBlankLine),
29            "IncorrectDelimiter" => Ok(LintKind::IncorrectDelimiter),
30            "KeyWithoutValue" => Ok(LintKind::KeyWithoutValue),
31            "LeadingCharacter" => Ok(LintKind::LeadingCharacter),
32            "LowercaseKey" => Ok(LintKind::LowercaseKey),
33            "QuoteCharacter" => Ok(LintKind::QuoteCharacter),
34            "SpaceCharacter" => Ok(LintKind::SpaceCharacter),
35            "SubstitutionKey" => Ok(LintKind::SubstitutionKey),
36            "TrailingWhitespace" => Ok(LintKind::TrailingWhitespace),
37            "UnorderedKey" => Ok(LintKind::UnorderedKey),
38            "ValueWithoutQuotes" => Ok(LintKind::ValueWithoutQuotes),
39            _ => Err(()),
40        }
41    }
42}
43
44impl fmt::Display for LintKind {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        write!(f, "{}", format!("{self:?}").replace("LintKind", ""))
47    }
48}
49
50#[cfg(feature = "clap")]
51impl clap::ValueEnum for LintKind {
52    fn value_variants<'a>() -> &'a [Self] {
53        &[
54            LintKind::DuplicatedKey,
55            LintKind::EndingBlankLine,
56            LintKind::ExtraBlankLine,
57            LintKind::IncorrectDelimiter,
58            LintKind::KeyWithoutValue,
59            LintKind::LeadingCharacter,
60            LintKind::LowercaseKey,
61            LintKind::QuoteCharacter,
62            LintKind::SpaceCharacter,
63            LintKind::SubstitutionKey,
64            LintKind::TrailingWhitespace,
65            LintKind::UnorderedKey,
66            LintKind::ValueWithoutQuotes,
67            LintKind::SchemaViolation,
68        ]
69    }
70
71    fn to_possible_value<'a>(&self) -> Option<clap::builder::PossibleValue> {
72        Some(match self {
73            LintKind::DuplicatedKey => clap::builder::PossibleValue::new("DuplicatedKey"),
74            LintKind::EndingBlankLine => clap::builder::PossibleValue::new("EndingBlankLine"),
75            LintKind::ExtraBlankLine => clap::builder::PossibleValue::new("ExtraBlankLine"),
76            LintKind::IncorrectDelimiter => clap::builder::PossibleValue::new("IncorrectDelimiter"),
77            LintKind::KeyWithoutValue => clap::builder::PossibleValue::new("KeyWithoutValue"),
78            LintKind::LeadingCharacter => clap::builder::PossibleValue::new("LeadingCharacter"),
79            LintKind::LowercaseKey => clap::builder::PossibleValue::new("LowercaseKey"),
80            LintKind::QuoteCharacter => clap::builder::PossibleValue::new("QuoteCharacter"),
81            LintKind::SpaceCharacter => clap::builder::PossibleValue::new("SpaceCharacter"),
82            LintKind::SubstitutionKey => clap::builder::PossibleValue::new("SubstitutionKey"),
83            LintKind::TrailingWhitespace => clap::builder::PossibleValue::new("TrailingWhitespace"),
84            LintKind::UnorderedKey => clap::builder::PossibleValue::new("UnorderedKey"),
85            LintKind::ValueWithoutQuotes => clap::builder::PossibleValue::new("ValueWithoutQuotes"),
86            LintKind::SchemaViolation => clap::builder::PossibleValue::new("SchemaViolation"),
87        })
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94
95    #[test]
96    fn test_str_to_lint_variant_conversion() {
97        let expected = <LintKind as FromStr>::from_str("DuplicatedKey").expect("parse lint");
98        assert_eq!(expected, LintKind::DuplicatedKey);
99    }
100
101    #[test]
102    fn test_invalid_lint_str_variant() {
103        assert_eq!(Err(()), <LintKind as FromStr>::from_str("FooBarLint"));
104    }
105
106    #[test]
107    fn test_lint_variant_display_output() {
108        let one = LintKind::EndingBlankLine;
109        let two = LintKind::DuplicatedKey;
110        let three = LintKind::SubstitutionKey;
111
112        assert_eq!(
113            "EndingBlankLine DuplicatedKey SubstitutionKey",
114            format!("{one} {two} {three}")
115        );
116    }
117}