Skip to main content

shep_core/protocol/request/
response_name.rs

1//! [`Response::name`]: which answer arrived, for an error that must not
2//! print its body.
3
4use super::Response;
5
6impl Response {
7    /// The variant's name, never its body, for an error saying which answer
8    /// arrived.
9    ///
10    /// A listing would flood the message, and [`Self::DogSection`] carries
11    /// credentials. Exhaustive here, so a new variant names itself.
12    #[must_use]
13    pub const fn name(&self) -> &'static str {
14        match self {
15            Self::Pong => "Pong",
16            Self::Flock(_) => "Flock",
17            Self::HostUsage(_) => "HostUsage",
18            Self::Described(_) => "Described",
19            Self::Started(_) => "Started",
20            Self::Added(_) => "Added",
21            Self::Drifted(_) => "Drifted",
22            Self::Applied(_) => "Applied",
23            Self::SheepConfig(_) => "SheepConfig",
24            Self::SheepEnvSet { .. } => "SheepEnvSet",
25            Self::SheepEnvBatch { .. } => "SheepEnvBatch",
26            Self::SheepFieldSet { .. } => "SheepFieldSet",
27            Self::DogSheepSettings { .. } => "DogSheepSettings",
28            Self::SheepDogSettingsSet { .. } => "SheepDogSettingsSet",
29            Self::DogConfigSet { .. } => "DogConfigSet",
30            Self::SecretsPut { .. } => "SecretsPut",
31            Self::Stopped(_) => "Stopped",
32            Self::Restarted { .. } => "Restarted",
33            Self::Reloading { .. } => "Reloading",
34            Self::Scaled(_) => "Scaled",
35            Self::SmitPainted(_) => "SmitPainted",
36            Self::Deleted(_) => "Deleted",
37            Self::Reopened(_) => "Reopened",
38            Self::Flushed(_) => "Flushed",
39            Self::Triggered(_) => "Triggered",
40            Self::Signalled(_) => "Signalled",
41            Self::SentLine(_) => "SentLine",
42            Self::RollSaved { .. } => "RollSaved",
43            Self::Mustered(_) => "Mustered",
44            Self::DogSection { .. } => "DogSection",
45            Self::DogStarted(_) => "DogStarted",
46            Self::DogStaleness { .. } => "DogStaleness",
47            Self::HandoverFitness { .. } => "HandoverFitness",
48            Self::Subscribed => "Subscribed",
49            Self::ShuttingDown => "ShuttingDown",
50        }
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::super::process::sample_info;
57    use super::*;
58
59    /// An error names the variant and a captured frame names the tag, so the
60    /// two have to agree. A sample of shapes: unit, listing, struct, secret.
61    #[test]
62    fn a_responses_name_is_its_wire_tag_in_the_variants_spelling() {
63        let responses = [
64            Response::Pong,
65            Response::Flock(vec![sample_info()]),
66            Response::HostUsage(None),
67            Response::RollSaved {
68                path: "/home/ada/.shep/flock.json".to_string(),
69                apps: 2,
70            },
71            Response::DogSection {
72                toml: "webhook = \"https://example.invalid/hook\"\n"
73                    .to_string()
74                    .into(),
75            },
76            Response::HandoverFitness { refusal: None },
77            Response::ShuttingDown,
78        ];
79        for response in responses {
80            let wire = serde_json::to_value(&response).unwrap();
81            let snake: String = response
82                .name()
83                .chars()
84                .enumerate()
85                .flat_map(|(at, c)| {
86                    let gap = (at > 0 && c.is_ascii_uppercase()).then_some('_');
87                    gap.into_iter().chain(c.to_lowercase())
88                })
89                .collect();
90            assert_eq!(wire["kind"], snake.as_str(), "{}", response.name());
91        }
92    }
93}