depo_api/request/
delete_shares.rs1use std::collections::HashSet;
2
3use bc_envelope::prelude::*;
4
5use crate::{
6 DELETE_SHARES_FUNCTION, Error, RECEIPT_PARAM, RECEIPT_PARAM_NAME, Result,
7 receipt::Receipt,
8 util::{Abbrev, FlankedFunction},
9};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct DeleteShares(HashSet<Receipt>);
17
18impl DeleteShares {
19 pub fn new<I, T>(iterable: I) -> Self
20 where
21 I: IntoIterator<Item = T>,
22 T: Clone + Into<Receipt>,
23 {
24 Self(
25 iterable
26 .into_iter()
27 .map(|item| item.clone().into())
28 .collect(),
29 )
30 }
31
32 pub fn receipts(&self) -> &HashSet<Receipt> { &self.0 }
33}
34
35impl From<DeleteShares> for Expression {
36 fn from(value: DeleteShares) -> Self {
37 let mut expression = Expression::new(DELETE_SHARES_FUNCTION);
38 for receipt in value.0.into_iter() {
39 expression = expression.with_parameter(RECEIPT_PARAM, receipt);
40 }
41 expression
42 }
43}
44
45impl TryFrom<Expression> for DeleteShares {
46 type Error = Error;
47
48 fn try_from(expression: Expression) -> Result<Self> {
49 let receipts = expression
50 .objects_for_parameter(RECEIPT_PARAM)
51 .into_iter()
52 .map(|parameter| {
53 parameter.try_into().map_err(|e| Error::InvalidParameter {
54 parameter: RECEIPT_PARAM_NAME.to_string(),
55 message: format!("failed to convert to Receipt: {}", e),
56 })
57 })
58 .collect::<Result<HashSet<Receipt>>>()?;
59 Ok(Self::new(receipts))
60 }
61}
62
63impl std::fmt::Display for DeleteShares {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 f.write_fmt(format_args!(
66 "{} {}",
67 "deleteShares".flanked_function(),
68 self.receipts().abbrev()
69 ))
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use bc_components::XID;
76 use indoc::indoc;
77
78 use super::*;
79
80 fn user_id() -> XID {
81 XID::from_data_ref(hex_literal::hex!(
82 "8712dfac3d0ebfa910736b2a9ee39d4b68f64222a77bcc0074f3f5f1c9216d30"
83 ))
84 .unwrap()
85 }
86
87 fn receipt_1() -> Receipt { Receipt::new(user_id(), b"data_1") }
88
89 fn receipt_2() -> Receipt { Receipt::new(user_id(), b"data_2") }
90
91 #[test]
92 fn test_request() {
93 bc_envelope::register_tags();
94
95 let receipts = vec![receipt_1(), receipt_2()];
96
97 let request = DeleteShares::new(receipts);
98 let expression: Expression = request.clone().into();
99 let request_envelope = expression.to_envelope();
100 #[rustfmt::skip]
102 assert_eq!(request_envelope.format(), indoc! {r#"
103 «"deleteShares"» [
104 ❰"receipt"❱: Bytes(32) [
105 'isA': "Receipt"
106 ]
107 ❰"receipt"❱: Bytes(32) [
108 'isA': "Receipt"
109 ]
110 ]
111 "#}.trim());
112 let decoded_expression =
113 Expression::try_from(request_envelope).unwrap();
114 let decoded = DeleteShares::try_from(decoded_expression).unwrap();
115 assert_eq!(request, decoded);
116 }
117}