depo_api/request/
get_recovery.rs

1use bc_envelope::prelude::*;
2use anyhow::{ Error, Result };
3use gstp::prelude::*;
4
5use crate::{ GET_RECOVERY_FUNCTION, util::{ Abbrev, FlankedFunction } };
6
7//
8// Request
9//
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct GetRecovery();
13
14impl GetRecovery {
15    pub fn new() -> Self {
16        Self()
17    }
18}
19
20impl Default for GetRecovery {
21    fn default() -> Self {
22        Self::new()
23    }
24}
25
26impl From<GetRecovery> for Expression {
27    fn from(_: GetRecovery) -> Self {
28        Expression::new(GET_RECOVERY_FUNCTION)
29    }
30}
31
32impl TryFrom<Expression> for GetRecovery {
33    type Error = Error;
34
35    fn try_from(_: Expression) -> Result<Self> {
36        Ok(Self::new())
37    }
38}
39
40impl std::fmt::Display for GetRecovery {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        f.write_fmt(format_args!("{}", "getRecovery".flanked_function()))
43    }
44}
45
46//
47// Response
48//
49
50#[derive(Debug, Clone, PartialEq, Eq)]
51pub struct GetRecoveryResult(Option<String>);
52
53impl GetRecoveryResult {
54    pub fn new(recovery: Option<String>) -> Self {
55        Self(recovery)
56    }
57
58    pub fn recovery(&self) -> Option<&str> {
59        self.0.as_deref()
60    }
61}
62
63impl From<GetRecoveryResult> for Envelope {
64    fn from(value: GetRecoveryResult) -> Self {
65        value.recovery().map_or_else(Envelope::null, Envelope::new)
66    }
67}
68
69impl TryFrom<Envelope> for GetRecoveryResult {
70    type Error = Error;
71
72    fn try_from(envelope: Envelope) -> Result<Self> {
73        let recovery = if envelope.is_null() { None } else { Some(envelope.extract_subject()?) };
74        Ok(Self::new(recovery))
75    }
76}
77
78impl TryFrom<SealedResponse> for GetRecoveryResult {
79    type Error = Error;
80
81    fn try_from(response: SealedResponse) -> Result<Self> {
82        response.result()?.clone().try_into()
83    }
84}
85
86impl std::fmt::Display for GetRecoveryResult {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        f.write_fmt(
89            format_args!("{} OK: {}", "getRecovery".flanked_function(), self.recovery().abbrev())
90        )
91    }
92}
93
94#[cfg(test)]
95mod tests {
96    use indoc::indoc;
97
98    use super::*;
99
100    #[test]
101    fn test_request() {
102        bc_envelope::register_tags();
103
104        let request = GetRecovery::new();
105        let expression: Expression = request.clone().into();
106        let request_envelope = expression.to_envelope();
107        #[rustfmt::skip]
108        assert_eq!(request_envelope.format(), indoc! {r#"
109            «"getRecovery"»
110        "#}.trim());
111        let decoded_expression = Expression::try_from(request_envelope).unwrap();
112        let decoded = GetRecovery::try_from(decoded_expression).unwrap();
113        assert_eq!(request, decoded);
114    }
115
116    #[test]
117    fn test_response() {
118        bc_envelope::register_tags();
119
120        let response = GetRecoveryResult::new(Some("Recovery Method".into()));
121        let response_envelope = response.to_envelope();
122        assert_eq!(
123            response_envelope.format(),
124            (
125                indoc! {
126                    r#"
127        "Recovery Method"
128        "#
129                }
130            ).trim()
131        );
132        let decoded = GetRecoveryResult::try_from(response_envelope).unwrap();
133        assert_eq!(response, decoded);
134
135        let response = GetRecoveryResult::new(None);
136        let response_envelope = response.to_envelope();
137        assert_eq!(
138            response_envelope.format(),
139            (
140                indoc! {
141                    r#"
142        null
143        "#
144                }
145            ).trim()
146        );
147        let decoded = GetRecoveryResult::try_from(response_envelope).unwrap();
148        assert_eq!(response, decoded);
149    }
150}