rusmpp_core/pdus/owned/
bind_resp.rs

1use rusmpp_macros::Rusmpp;
2
3use crate::{
4    pdus::owned::Pdu,
5    tlvs::owned::{Tlv, TlvValue},
6    types::owned::COctetString,
7    values::*,
8};
9
10macro_rules! bind_resp {
11    ($name:ident) => {
12        #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
13        #[rusmpp(decode = owned, test = skip)]
14        #[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
15        #[cfg_attr(feature = "serde", derive(::serde::Serialize))]
16        #[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
17        pub struct $name {
18            /// MC identifier.
19            ///
20            /// Identifies the MC to the ESME.
21            pub system_id: COctetString<1, 16>,
22            /// `SMPP` version supported by MC. [`ScInterfaceVersion`].
23            #[rusmpp(length = "checked")]
24            sc_interface_version: Option<Tlv>,
25        }
26
27        impl $name {
28            pub fn new(
29                system_id: COctetString<1, 16>,
30                sc_interface_version: Option<InterfaceVersion>,
31            ) -> Self {
32                Self {
33                    system_id,
34                    sc_interface_version: sc_interface_version
35                        .map(TlvValue::ScInterfaceVersion)
36                        .map(From::from),
37                }
38            }
39
40            pub const fn sc_interface_version_tlv(&self) -> Option<&Tlv> {
41                self.sc_interface_version.as_ref()
42            }
43
44            pub fn sc_interface_version(&self) -> Option<InterfaceVersion> {
45                self.sc_interface_version_tlv()
46                    .and_then(|tlv| match tlv.value() {
47                        Some(TlvValue::ScInterfaceVersion(value)) => Some(value),
48                        _ => None,
49                    })
50                    .copied()
51            }
52
53            pub fn set_sc_interface_version(
54                &mut self,
55                sc_interface_version: Option<InterfaceVersion>,
56            ) {
57                self.sc_interface_version = sc_interface_version
58                    .map(TlvValue::ScInterfaceVersion)
59                    .map(From::from);
60            }
61
62            ::pastey::paste! {
63                pub fn builder() -> [<$name Builder>] {
64                    [<$name Builder>]::new()
65                }
66            }
67        }
68
69        ::pastey::paste! {
70            #[derive(Debug, Default)]
71            pub struct [<$name Builder>] {
72               inner: $name,
73            }
74
75            impl [<$name Builder>] {
76                pub fn new() -> Self {
77                    Self::default()
78                }
79
80                pub fn system_id(mut self, system_id: COctetString<1, 16>) -> Self {
81                    self.inner.system_id = system_id;
82                    self
83                }
84
85                pub fn sc_interface_version(
86                    mut self,
87                    sc_interface_version: Option<InterfaceVersion>,
88                ) -> Self {
89                    self.inner.set_sc_interface_version(sc_interface_version);
90                    self
91                }
92
93                pub fn build(self) -> $name {
94                    self.inner
95                }
96            }
97        }
98    };
99}
100
101bind_resp!(BindTransmitterResp);
102bind_resp!(BindReceiverResp);
103bind_resp!(BindTransceiverResp);
104
105impl From<BindTransmitterResp> for Pdu {
106    fn from(value: BindTransmitterResp) -> Self {
107        Self::BindTransmitterResp(value)
108    }
109}
110
111impl From<BindReceiverResp> for Pdu {
112    fn from(value: BindReceiverResp) -> Self {
113        Self::BindReceiverResp(value)
114    }
115}
116
117impl From<BindTransceiverResp> for Pdu {
118    fn from(value: BindTransceiverResp) -> Self {
119        Self::BindTransceiverResp(value)
120    }
121}
122
123#[cfg(test)]
124mod tests {
125    use std::str::FromStr;
126
127    use crate::tests::TestInstance;
128
129    use super::*;
130
131    impl TestInstance for BindTransmitterResp {
132        fn instances() -> alloc::vec::Vec<Self> {
133            alloc::vec![
134                Self::default(),
135                Self::builder()
136                    .system_id(COctetString::from_str("system_id").unwrap())
137                    .sc_interface_version(Some(InterfaceVersion::Smpp5_0))
138                    .build(),
139            ]
140        }
141    }
142
143    impl TestInstance for BindReceiverResp {
144        fn instances() -> alloc::vec::Vec<Self> {
145            alloc::vec![
146                Self::default(),
147                Self::builder()
148                    .system_id(COctetString::from_str("system_id").unwrap())
149                    .sc_interface_version(Some(InterfaceVersion::Smpp3_4))
150                    .build(),
151            ]
152        }
153    }
154
155    impl TestInstance for BindTransceiverResp {
156        fn instances() -> alloc::vec::Vec<Self> {
157            alloc::vec![
158                Self::default(),
159                Self::builder()
160                    .system_id(COctetString::from_str("system_id").unwrap())
161                    .sc_interface_version(Some(InterfaceVersion::Smpp3_3OrEarlier(1)))
162                    .build(),
163            ]
164        }
165    }
166
167    #[test]
168    fn encode_decode() {
169        crate::tests::owned::encode_decode_with_length_test_instances::<BindTransmitterResp>();
170        crate::tests::owned::encode_decode_with_length_test_instances::<BindReceiverResp>();
171        crate::tests::owned::encode_decode_with_length_test_instances::<BindTransceiverResp>();
172    }
173}