depo_api/request/
update_recovery.rs

1use anyhow::{Error, Result};
2use bc_envelope::prelude::*;
3
4use crate::{
5    RECOVERY_METHOD_PARAM, UPDATE_RECOVERY_FUNCTION,
6    util::{Abbrev, FlankedFunction},
7};
8
9//
10// Request
11//
12
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct UpdateRecovery(Option<String>);
15
16impl UpdateRecovery {
17    pub fn new(recovery: Option<String>) -> Self { Self(recovery) }
18
19    pub fn recovery(&self) -> Option<&String> { self.0.as_ref() }
20}
21
22impl From<UpdateRecovery> for Expression {
23    fn from(value: UpdateRecovery) -> Self {
24        let method = if let Some(recovery) = value.0.clone() {
25            recovery.to_envelope()
26        } else {
27            Envelope::null()
28        };
29        Expression::new(UPDATE_RECOVERY_FUNCTION)
30            .with_parameter(RECOVERY_METHOD_PARAM, method)
31    }
32}
33
34impl TryFrom<Expression> for UpdateRecovery {
35    type Error = Error;
36
37    fn try_from(expression: Expression) -> Result<Self> {
38        let recovery_object =
39            expression.object_for_parameter(RECOVERY_METHOD_PARAM)?;
40        let recovery = if recovery_object.is_null() {
41            None
42        } else {
43            Some(recovery_object.extract_subject()?)
44        };
45        Ok(Self::new(recovery))
46    }
47}
48
49impl std::fmt::Display for UpdateRecovery {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        f.write_fmt(format_args!(
52            "{} to {}",
53            "updateRecovery".flanked_function(),
54            self.recovery().abbrev()
55        ))
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use indoc::indoc;
62
63    use super::*;
64
65    #[test]
66    fn test_request() {
67        bc_envelope::register_tags();
68
69        let recovery = "recovery".to_string();
70
71        let request = UpdateRecovery::new(Some(recovery));
72        let expression: Expression = request.clone().into();
73        let request_envelope = expression.to_envelope();
74        // println!("{}", request_envelope.format());
75        #[rustfmt::skip]
76        assert_eq!(request_envelope.format(), indoc! {r#"
77            «"updateRecovery"» [
78                ❰"recoveryMethod"❱: "recovery"
79            ]
80        "#}.trim());
81        let decoded_expression =
82            Expression::try_from(request_envelope).unwrap();
83        let decoded = UpdateRecovery::try_from(decoded_expression).unwrap();
84        assert_eq!(request, decoded);
85    }
86}