depo_api/request/
store_share.rs

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