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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use crate::{check_environment, error::Error, str_extension::StrExtension};
use std::{fmt::Display, str::FromStr};

pub type DomainName = String;

const ACME_VALIDATION_DELETE: &str = "acme-validation-delete";
const ACME_VALIDATION_SET: &str = "acme-validation-set";
const LIST: &str = "list";

#[derive(Debug, PartialEq)]
pub enum DnsCommand {
    /// # Example
    ///
    /// ```
    /// use transip_command::{DnsCommand, TransipCommand};
    ///
    /// let commandline = "dns list lkdjfie.nl";
    /// assert_eq!(
    ///     commandline.parse::<TransipCommand>().unwrap(),
    ///     TransipCommand::Dns(
    ///         DnsCommand::List(
    ///             "lkdjfie.nl".to_owned()
    ///         )
    ///     ),
    /// );
    /// ```
    List(DomainName),

    /// # Example
    ///
    /// ```
    /// use transip_command::{DnsCommand, TransipCommand};
    ///
    /// let commandline = "dns acme-validation-delete lkdfjf.nl";
    /// assert_eq!(
    ///     commandline.parse::<TransipCommand>().unwrap(),
    ///     TransipCommand::Dns(
    ///         DnsCommand::AcmeValidationDelete(
    ///             "lkdfjf.nl".to_owned()
    ///         )
    ///     ),
    /// );
    /// ```
    AcmeValidationDelete(DomainName),

    /// # Example
    ///
    /// ```
    /// use transip_command::{DnsCommand, TransipCommand};
    ///
    /// let commandline = "dns acme-validation-set lkdfjf.nl oe8rtg";
    /// assert_eq!(
    ///     commandline.parse::<TransipCommand>().unwrap(),
    ///     TransipCommand::Dns(
    ///         DnsCommand::AcmeValidationSet(
    ///             "lkdfjf.nl".to_owned(),
    ///             "oe8rtg".to_owned(),
    ///         )
    ///     ),
    /// );
    /// ```
    AcmeValidationSet(DomainName, String),
}

impl Display for DnsCommand {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            DnsCommand::AcmeValidationDelete(name) => {
                write!(f, "{} {}", ACME_VALIDATION_DELETE, name)
            }
            DnsCommand::List(name) => write!(f, "{} {}", LIST, name),
            DnsCommand::AcmeValidationSet(name, challenge) => {
                write!(f, "{} {} {}", ACME_VALIDATION_SET, name, challenge)
            }
        }
    }
}

impl FromStr for DnsCommand {
    type Err = Error;

    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
        if let Some(domain_name) = s.one_param(ACME_VALIDATION_DELETE) {
            return Ok(DnsCommand::AcmeValidationDelete(check_environment(
                domain_name,
            )?));
        }
        if let Some((domain_name, challenge)) = s.two_params(ACME_VALIDATION_SET) {
            return Ok(DnsCommand::AcmeValidationSet(
                check_environment(domain_name)?,
                check_environment(challenge)?,
            ));
        }
        if let Some(domain_name) = s.one_param(LIST) {
            return Ok(DnsCommand::List(check_environment(domain_name)?));
        }
        Err(Error::ParseDnsCommand(s.to_owned()))
    }
}

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

    #[test]
    fn display() {
        assert_eq!(
            DnsCommand::List("paulmin.nl".to_owned()).to_string(),
            "list paulmin.nl".to_owned(),
        );

        assert_eq!(
            DnsCommand::AcmeValidationDelete("paulmin.nl".to_owned()).to_string(),
            "acme-validation-delete paulmin.nl".to_owned(),
        );

        assert_eq!(
            DnsCommand::AcmeValidationSet("paulmin.nl".to_owned(), "hallo".to_owned()).to_string(),
            "acme-validation-set paulmin.nl hallo".to_owned(),
        );
    }

    #[test]
    fn from_str() {
        assert_eq!(
            "acme-validation-set ${CERTBOT_DOMAIN} ${CERTBOT_VALIDATION}"
                .parse::<DnsCommand>()
                .unwrap(),
            DnsCommand::AcmeValidationSet("paulmin.nl".to_owned(), "876543".to_owned())
        );
    }
}