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