rusmpp_core/pdus/owned/
sm_resp.rs1use 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 message_id: COctetString<1, 65>,
21 #[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}