rusmpp_core/pdus/owned/
sm_resp.rs

1use rusmpp_macros::Rusmpp;
2
3use crate::{
4    pdus::owned::Pdu,
5    tlvs::owned::{MessageDeliveryResponseTlvValue, Tlv},
6    types::owned::COctetString,
7};
8
9macro_rules! sm_resp {
10    ($name:ident) => {
11        #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
12        #[rusmpp(decode = owned, test = skip)]
13        #[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
14        #[cfg_attr(feature = "serde", derive(::serde::Serialize))]
15        #[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
16        pub struct $name {
17            /// This field contains the MC message ID of the submitted message.
18            /// It may be used at a later stage to query the status of a message,
19            /// cancel or replace the message.
20            message_id: COctetString<1, 65>,
21            /// Message delivery response TLVs ([`MessageDeliveryResponseTlvValue`])
22            #[rusmpp(length = "unchecked")]
23            tlvs: alloc::vec::Vec<Tlv>,
24        }
25
26        impl $name {
27            pub fn new(
28                message_id: COctetString<1, 65>,
29                tlvs: alloc::vec::Vec<MessageDeliveryResponseTlvValue>,
30            ) -> Self {
31                let tlvs = tlvs.into_iter().map(From::from).collect();
32
33                Self { message_id, tlvs }
34            }
35
36            pub fn message_id(&self) -> &COctetString<1, 65> {
37                &self.message_id
38            }
39
40            pub fn tlvs(&self) -> &[Tlv] {
41                &self.tlvs
42            }
43
44            pub fn set_tlvs(&mut self, tlvs: alloc::vec::Vec<MessageDeliveryResponseTlvValue>) {
45                self.tlvs = tlvs.into_iter().map(From::from).collect();
46            }
47
48            pub fn push_tlv(&mut self, tlv: impl Into<MessageDeliveryResponseTlvValue>) {
49                self.tlvs.push(Tlv::from(tlv.into()));
50            }
51
52            ::pastey::paste! {
53                pub fn builder() -> [<$name Builder>] {
54                    [<$name Builder>]::new()
55                }
56            }
57        }
58
59        ::pastey::paste! {
60            #[derive(Debug, Default)]
61            pub struct [<$name Builder>] {
62               inner: $name,
63            }
64
65            impl [<$name Builder>] {
66                pub fn new() -> Self {
67                    Self::default()
68                }
69
70                pub fn message_id(mut self, message_id: COctetString<1, 65>) -> Self {
71                    self.inner.message_id = message_id;
72                    self
73                }
74
75                pub fn tlvs(
76                    mut self,
77                    tlvs: alloc::vec::Vec<MessageDeliveryResponseTlvValue>,
78                ) -> Self {
79                    self.inner.set_tlvs(tlvs);
80                    self
81                }
82
83                pub fn push_tlv(mut self, tlv: impl Into<MessageDeliveryResponseTlvValue>) -> Self {
84                    self.inner.push_tlv(tlv);
85                    self
86                }
87
88                pub fn build(self) -> $name {
89                    self.inner
90                }
91            }
92        }
93    };
94}
95
96sm_resp!(DeliverSmResp);
97sm_resp!(DataSmResp);
98
99impl From<DeliverSmResp> for Pdu {
100    fn from(value: DeliverSmResp) -> Self {
101        Self::DeliverSmResp(value)
102    }
103}
104
105impl From<DataSmResp> for Pdu {
106    fn from(value: DataSmResp) -> Self {
107        Self::DataSmResp(value)
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use std::str::FromStr;
114
115    use crate::{tests::TestInstance, values::*};
116
117    use super::*;
118
119    impl TestInstance for DeliverSmResp {
120        fn instances() -> alloc::vec::Vec<Self> {
121            alloc::vec![
122                Self::default(),
123                Self::builder()
124                    .message_id(COctetString::from_str("123456789012345678").unwrap())
125                    .build(),
126                Self::builder()
127                    .message_id(COctetString::from_str("123456789012345678").unwrap())
128                    .tlvs(alloc::vec![
129                        MessageDeliveryResponseTlvValue::AdditionalStatusInfoText(
130                            COctetString::from_str("Octets").unwrap(),
131                        ),
132                        MessageDeliveryResponseTlvValue::DeliveryFailureReason(
133                            DeliveryFailureReason::TemporaryNetworkError,
134                        ),
135                    ])
136                    .build(),
137            ]
138        }
139    }
140
141    impl TestInstance for DataSmResp {
142        fn instances() -> alloc::vec::Vec<Self> {
143            alloc::vec![
144                Self::default(),
145                Self::builder()
146                    .message_id(COctetString::from_str("123456789012345678").unwrap())
147                    .build(),
148                Self::builder()
149                    .message_id(COctetString::from_str("123456789012345678").unwrap())
150                    .tlvs(alloc::vec![
151                        MessageDeliveryResponseTlvValue::AdditionalStatusInfoText(
152                            COctetString::from_str("Octets on steroids").unwrap(),
153                        ),
154                        MessageDeliveryResponseTlvValue::NetworkErrorCode(NetworkErrorCode::new(
155                            ErrorCodeNetworkType::SmppError,
156                            1,
157                        )),
158                    ])
159                    .build(),
160            ]
161        }
162    }
163
164    #[test]
165    fn encode_decode() {
166        crate::tests::owned::encode_decode_with_length_test_instances::<DeliverSmResp>();
167        crate::tests::owned::encode_decode_with_length_test_instances::<DataSmResp>();
168    }
169}