Skip to main content

bnto_core/
input_mode.rs

1//! `InputMode` — how a recipe receives its input, plus its wire-string form
2//! (the input node's `mode` param: `file-upload`, `url`, `text`, `none`).
3
4use std::fmt;
5use std::str::FromStr;
6
7/// How the recipe expects to receive its input data.
8/// Read from the input node's `mode` parameter.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10pub enum InputMode {
11    /// User uploads files (default). CLI reads file paths from disk.
12    #[default]
13    FileUpload,
14    /// User provides a URL. CLI accepts a URL string.
15    Url,
16    /// User provides text content. CLI accepts a text string.
17    Text,
18    /// Recipe takes no input at all — all configuration comes from node
19    /// fields. Used by utility recipes (session managers, system toggles)
20    /// where there is nothing to feed in.
21    None,
22}
23
24impl InputMode {
25    /// The wire string used for the input node's `mode` param.
26    pub fn as_str(self) -> &'static str {
27        match self {
28            InputMode::FileUpload => "file-upload",
29            InputMode::Url => "url",
30            InputMode::Text => "text",
31            InputMode::None => "none",
32        }
33    }
34}
35
36impl fmt::Display for InputMode {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        f.write_str(self.as_str())
39    }
40}
41
42impl FromStr for InputMode {
43    type Err = String;
44
45    fn from_str(s: &str) -> Result<Self, Self::Err> {
46        match s {
47            "file-upload" => Ok(InputMode::FileUpload),
48            "url" => Ok(InputMode::Url),
49            "text" => Ok(InputMode::Text),
50            "none" => Ok(InputMode::None),
51            other => Err(format!("unknown input mode: {other}")),
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    const ALL: [(InputMode, &str); 4] = [
61        (InputMode::FileUpload, "file-upload"),
62        (InputMode::Url, "url"),
63        (InputMode::Text, "text"),
64        (InputMode::None, "none"),
65    ];
66
67    #[test]
68    fn as_str_returns_wire_string() {
69        for (mode, wire) in ALL {
70            assert_eq!(mode.as_str(), wire);
71        }
72    }
73
74    #[test]
75    fn display_matches_as_str() {
76        for (mode, wire) in ALL {
77            assert_eq!(mode.to_string(), wire);
78        }
79    }
80
81    #[test]
82    fn from_str_round_trips() {
83        for (mode, wire) in ALL {
84            assert_eq!(wire.parse::<InputMode>(), Ok(mode));
85        }
86    }
87
88    #[test]
89    fn from_str_rejects_unknown_mode() {
90        let err = "carrier-pigeon".parse::<InputMode>().unwrap_err();
91        assert_eq!(err, "unknown input mode: carrier-pigeon");
92    }
93}