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
use crate::{
    BuilderError,
    DataType,
};

/// An argument.
///
/// Specifically, this is a parameter, not a value.
#[derive(Debug)]
pub struct ArgumentParam {
    name: Box<str>,
    kind: DataType,
    description: Box<str>,
    required: bool,
}

impl ArgumentParam {
    /// Get the name of the argument
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Get the argument kind
    pub fn kind(&self) -> DataType {
        self.kind
    }

    /// Get the description of the argument
    pub fn description(&self) -> &str {
        &self.description
    }

    /// Check if the argument is required
    pub fn required(&self) -> bool {
        self.required
    }
}

/// An argument param builder
#[derive(Debug)]
pub struct ArgumentParamBuilder<'a, 'b> {
    name: Option<&'a str>,
    kind: Option<DataType>,
    description: Option<&'b str>,
    required: bool,
}

impl<'a, 'b> ArgumentParamBuilder<'a, 'b> {
    /// Make a new [`ArgumentParamBuilder`].
    pub fn new() -> Self {
        Self {
            name: None,
            kind: None,
            description: None,
            required: false,
        }
    }

    /// Set the name
    pub fn name(&mut self, name: &'a str) -> &mut Self {
        self.name = Some(name);
        self
    }

    /// Set the kind
    pub fn kind(&mut self, kind: DataType) -> &mut Self {
        self.kind = Some(kind);
        self
    }

    /// Set the description
    pub fn description(&mut self, description: &'b str) -> &mut Self {
        self.description = Some(description);
        self
    }

    /// Set if the argument is required
    pub fn required(&mut self, required: bool) -> &mut Self {
        self.required = required;
        self
    }

    /// Build the argument param
    pub fn build(&mut self) -> Result<ArgumentParam, BuilderError> {
        #[allow(clippy::or_fun_call)]
        let name = self.name.ok_or(BuilderError::MissingField("name"))?;
        #[allow(clippy::or_fun_call)]
        let kind = self.kind.ok_or(BuilderError::MissingField("kind"))?;
        #[allow(clippy::or_fun_call)]
        let description = self
            .description
            .ok_or(BuilderError::MissingField("description"))?;

        Ok(ArgumentParam {
            name: name.into(),
            kind,
            description: description.into(),
            required: self.required,
        })
    }
}

impl<'a, 'b> Default for ArgumentParamBuilder<'a, 'b> {
    fn default() -> Self {
        Self::new()
    }
}