rusmpp_core/pdus/owned/
submit_multi_resp.rs

1use rusmpp_macros::Rusmpp;
2
3use crate::{
4    pdus::owned::Pdu,
5    tlvs::owned::{MessageSubmissionResponseTlvValue, Tlv},
6    types::owned::COctetString,
7    values::owned::*,
8};
9
10#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
11#[rusmpp(decode = owned, test = skip)]
12#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
13#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
14#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
15pub struct SubmitMultiResp {
16    /// This field contains the MC message ID of the submitted
17    /// message. It may be used at a later stage to query the status
18    /// of a message, cancel or replace the message.
19    pub message_id: COctetString<1, 65>,
20    /// The number of messages to destination SME addresses that
21    /// were unsuccessfully submitted to the MC. This is followed by
22    /// the specified number of unsuccessful SMEs, each
23    /// specified in a unsuccess_sme field.
24    no_unsuccess: u8,
25    /// Unsuccessful SME.
26    ///
27    /// (Composite Field).
28    #[rusmpp(count = no_unsuccess)]
29    unsuccess_sme: alloc::vec::Vec<UnsuccessSme>,
30    /// Message submission response TLVs ([`MessageSubmissionResponseTlvValue`])
31    #[rusmpp(length = "unchecked")]
32    tlvs: alloc::vec::Vec<Tlv>,
33}
34
35impl SubmitMultiResp {
36    pub fn new(
37        message_id: COctetString<1, 65>,
38        unsuccess_sme: alloc::vec::Vec<UnsuccessSme>,
39        tlvs: alloc::vec::Vec<impl Into<MessageSubmissionResponseTlvValue>>,
40    ) -> Self {
41        let no_unsuccess = unsuccess_sme.len() as u8;
42
43        let tlvs = tlvs.into_iter().map(Into::into).map(From::from).collect();
44
45        Self {
46            message_id,
47            no_unsuccess,
48            unsuccess_sme,
49            tlvs,
50        }
51    }
52
53    pub fn no_unsuccess(&self) -> u8 {
54        self.no_unsuccess
55    }
56
57    pub fn unsuccess_sme(&self) -> &[UnsuccessSme] {
58        &self.unsuccess_sme
59    }
60
61    pub fn set_unsuccess_sme(&mut self, unsuccess_sme: alloc::vec::Vec<UnsuccessSme>) {
62        self.unsuccess_sme = unsuccess_sme;
63        self.no_unsuccess = self.unsuccess_sme.len() as u8;
64    }
65
66    pub fn push_unsuccess_sme(&mut self, unsuccess_sme: UnsuccessSme) {
67        self.unsuccess_sme.push(unsuccess_sme);
68        self.no_unsuccess = self.unsuccess_sme.len() as u8;
69    }
70
71    pub fn clear_unsuccess_sme(&mut self) {
72        self.unsuccess_sme.clear();
73        self.no_unsuccess = self.unsuccess_sme.len() as u8;
74    }
75
76    pub fn tlvs(&self) -> &[Tlv] {
77        &self.tlvs
78    }
79
80    pub fn set_tlvs(
81        &mut self,
82        tlvs: alloc::vec::Vec<impl Into<MessageSubmissionResponseTlvValue>>,
83    ) {
84        self.tlvs = tlvs.into_iter().map(Into::into).map(From::from).collect();
85    }
86
87    pub fn clear_tlvs(&mut self) {
88        self.tlvs.clear();
89    }
90
91    pub fn push_tlv(&mut self, tlv: impl Into<MessageSubmissionResponseTlvValue>) {
92        self.tlvs.push(Tlv::from(tlv.into()));
93    }
94
95    pub fn builder() -> SubmitMultiRespBuilder {
96        SubmitMultiRespBuilder::new()
97    }
98}
99
100impl From<SubmitMultiResp> for Pdu {
101    fn from(value: SubmitMultiResp) -> Self {
102        Self::SubmitMultiResp(value)
103    }
104}
105
106#[derive(Debug, Default)]
107pub struct SubmitMultiRespBuilder {
108    inner: SubmitMultiResp,
109}
110
111impl SubmitMultiRespBuilder {
112    pub fn new() -> Self {
113        Self::default()
114    }
115
116    pub fn message_id(mut self, message_id: COctetString<1, 65>) -> Self {
117        self.inner.message_id = message_id;
118        self
119    }
120
121    pub fn unsuccess_sme(mut self, unsuccess_sme: alloc::vec::Vec<UnsuccessSme>) -> Self {
122        self.inner.set_unsuccess_sme(unsuccess_sme);
123        self
124    }
125
126    pub fn push_unsuccess_sme(mut self, unsuccess_sme: UnsuccessSme) -> Self {
127        self.inner.push_unsuccess_sme(unsuccess_sme);
128        self
129    }
130
131    pub fn clear_unsuccess_sme(mut self) -> Self {
132        self.inner.clear_unsuccess_sme();
133        self
134    }
135
136    pub fn tlvs(
137        mut self,
138        tlvs: alloc::vec::Vec<impl Into<MessageSubmissionResponseTlvValue>>,
139    ) -> Self {
140        self.inner.set_tlvs(tlvs);
141        self
142    }
143
144    pub fn clear_tlvs(mut self) -> Self {
145        self.inner.clear_tlvs();
146        self
147    }
148
149    pub fn push_tlv(mut self, tlv: impl Into<MessageSubmissionResponseTlvValue>) -> Self {
150        self.inner.push_tlv(tlv);
151        self
152    }
153
154    pub fn build(self) -> SubmitMultiResp {
155        self.inner
156    }
157}
158
159#[cfg(test)]
160mod tests {
161    use std::str::FromStr;
162
163    use crate::{CommandStatus, tests::TestInstance, values::*};
164
165    use super::*;
166
167    impl TestInstance for SubmitMultiResp {
168        fn instances() -> alloc::vec::Vec<Self> {
169            alloc::vec![
170                Self::default(),
171                Self::builder()
172                    .message_id(COctetString::from_str("1234567890").unwrap())
173                    .build(),
174                Self::builder()
175                    .message_id(COctetString::from_str("1234567890").unwrap())
176                    .push_unsuccess_sme(UnsuccessSme::default())
177                    .push_unsuccess_sme(UnsuccessSme::new(
178                        Ton::International,
179                        Npi::Data,
180                        COctetString::from_str("1234567890").unwrap(),
181                        CommandStatus::EsmeRunknownerr,
182                    ))
183                    .build(),
184                Self::builder()
185                    .message_id(COctetString::from_str("1234567890").unwrap())
186                    .push_tlv(MessageSubmissionResponseTlvValue::DpfResult(
187                        DpfResult::NotSet,
188                    ))
189                    .push_tlv(MessageSubmissionResponseTlvValue::NetworkErrorCode(
190                        NetworkErrorCode::new(ErrorCodeNetworkType::Is95AccessDeniedReason, 0x01),
191                    ))
192                    .build(),
193            ]
194        }
195    }
196
197    #[test]
198    fn encode_decode() {
199        crate::tests::owned::encode_decode_with_length_test_instances::<SubmitMultiResp>();
200    }
201
202    #[test]
203    fn count() {
204        let submit_multi = SubmitMultiResp::default();
205
206        assert_eq!(submit_multi.no_unsuccess(), 0);
207        assert!(submit_multi.unsuccess_sme().is_empty());
208
209        let submit_multi = SubmitMultiResp::builder()
210            .unsuccess_sme(alloc::vec![
211                UnsuccessSme::default(),
212                UnsuccessSme::new(
213                    Ton::International,
214                    Npi::Data,
215                    COctetString::from_str("1234567890").unwrap(),
216                    CommandStatus::EsmeRunknownerr,
217                ),
218            ])
219            .build();
220
221        assert_eq!(submit_multi.no_unsuccess(), 2);
222        assert_eq!(submit_multi.unsuccess_sme().len(), 2);
223
224        let submit_multi = SubmitMultiResp::builder()
225            .push_unsuccess_sme(UnsuccessSme::default())
226            .push_unsuccess_sme(UnsuccessSme::new(
227                Ton::International,
228                Npi::Data,
229                COctetString::from_str("1234567890").unwrap(),
230                CommandStatus::EsmeRunknownerr,
231            ))
232            .build();
233
234        assert_eq!(submit_multi.no_unsuccess(), 2);
235        assert_eq!(submit_multi.unsuccess_sme().len(), 2);
236
237        let submit_multi = SubmitMultiResp::builder()
238            .push_unsuccess_sme(UnsuccessSme::default())
239            .push_unsuccess_sme(UnsuccessSme::new(
240                Ton::International,
241                Npi::Data,
242                COctetString::from_str("1234567890").unwrap(),
243                CommandStatus::EsmeRunknownerr,
244            ))
245            .clear_unsuccess_sme()
246            .build();
247
248        assert_eq!(submit_multi.no_unsuccess(), 0);
249        assert!(submit_multi.unsuccess_sme().is_empty());
250    }
251}