hellman_output/
lib.rs

1use std::{fmt::Display, str::FromStr, string::ParseError};
2
3/// Helper for the following requirements for output:
4///
5/// - Any stdout output line with a required result must have OUTPUT as the first word (token).
6/// - All numerical values required by an assignment must have whitespace (which includes end of line) around them.
7/// - Required textual output should be surrounded by single colons (:).
8/// - The order for results is assignment specific and important, they must emanate from the application in the order dictated by the assignment.
9#[derive(Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
10pub struct HellmanOutput(String);
11
12impl FromStr for HellmanOutput {
13    type Err = ParseError;
14
15    fn from_str(s: &str) -> Result<Self, Self::Err> {
16        Ok(Self::default().push_str(s))
17    }
18}
19
20impl Display for HellmanOutput {
21    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22        write!(f, "OUTPUT {}", self.0.trim_end())
23    }
24}
25
26impl HellmanOutput {
27    /// Push a number to the output string
28    /// Accepts anything that implements Display
29    pub fn push_numeric(&self, num: impl Display) -> Self {
30        let num_str = &format!("{} ", num);
31        Self(self.0.clone() + num_str)
32    }
33
34    /// Push a textual element to the output string
35    pub fn push_str(&self, s: &str) -> Self {
36        let new_addition = &format!(":{}: ", s);
37        Self(self.0.clone() + new_addition)
38    }
39
40    /// Push a textual element to the output string, translated with alphabet encoding
41    pub fn push_alphabet_encode(&self, s: &str) -> Self {
42        let new_addition = &format!(":{}: ", alphabet_encoding::encode(s.to_owned()));
43        Self(self.0.clone() + new_addition)
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use std::str::FromStr;
50
51    use crate::HellmanOutput;
52
53    #[test]
54    fn from_string() {
55        let s = "Fresh Avacado";
56
57        assert_eq!(
58            &HellmanOutput::from_str(s).unwrap().to_string(),
59            "OUTPUT :Fresh Avacado:"
60        );
61    }
62
63    #[test]
64    fn push_string() {
65        let s = "Fresh Avacado";
66        let output = &HellmanOutput::default().push_str(s).push_str(s);
67
68        assert_eq!(
69            &output.to_string(),
70            "OUTPUT :Fresh Avacado: :Fresh Avacado:"
71        );
72    }
73
74    #[test]
75    fn push_numeric() {
76        let s = "Fresh Avacado";
77        let output = &HellmanOutput::default()
78            .push_str(s)
79            .push_numeric(13)
80            .push_str(s)
81            .push_numeric(1.1);
82
83        assert_eq!(
84            &output.to_string(),
85            "OUTPUT :Fresh Avacado: 13 :Fresh Avacado: 1.1"
86        );
87    }
88}