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
41#[cfg(test)]
42mod tests {
43    use std::str::FromStr;
44
45    use crate::HellmanOutput;
46
47    #[test]
48    fn from_string() {
49        let s = "Fresh Avacado";
50
51        assert_eq!(
52            &HellmanOutput::from_str(s).unwrap().to_string(),
53            "OUTPUT :Fresh Avacado:"
54        );
55    }
56
57    #[test]
58    fn push_string() {
59        let s = "Fresh Avacado";
60        let output = &HellmanOutput::default().push_str(s).push_str(s);
61
62        assert_eq!(
63            &output.to_string(),
64            "OUTPUT :Fresh Avacado: :Fresh Avacado:"
65        );
66    }
67
68    #[test]
69    fn push_numeric() {
70        let s = "Fresh Avacado";
71        let output = &HellmanOutput::default()
72            .push_str(s)
73            .push_numeric(13)
74            .push_str(s)
75            .push_numeric(1.1);
76
77        assert_eq!(
78            &output.to_string(),
79            "OUTPUT :Fresh Avacado: 13 :Fresh Avacado: 1.1"
80        );
81    }
82}