rusmpp_core/pdus/owned/
bind.rs

1use rusmpp_macros::Rusmpp;
2
3use crate::{pdus::owned::Pdu, types::owned::COctetString, values::*};
4
5macro_rules! bind {
6    ($name:ident) => {
7        #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
8        #[rusmpp(decode = owned, test = skip)]
9        #[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
10        #[cfg_attr(feature = "serde", derive(::serde::Serialize))]
11        #[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
12        pub struct $name {
13            /// Identifies the ESME system
14            /// requesting to bind with the MC.
15            pub system_id: COctetString<1, 16>,
16            /// The password may be used by the
17            /// MC to authenticate the ESME
18            /// requesting to bind.
19            pub password: COctetString<1, 9>,
20            /// Identifies the type of ESME system
21            /// requesting to bind with the MC.
22            pub system_type: COctetString<1, 13>,
23            /// Identifies the version of the `SMPP`
24            /// protocol supported by the ESME.
25            pub interface_version: InterfaceVersion,
26            /// Type of Number (TON) for ESME
27            /// address(es) served via this `SMPP` session.
28            ///
29            /// Set to NULL (Unknown) if not known.
30            pub addr_ton: Ton,
31            /// Numbering Plan Indicator (NPI) for
32            /// ESME address(es) served via this `SMPP` session.
33            ///
34            /// Set to NULL (Unknown) if not known.
35            pub addr_npi: Npi,
36            /// A single ESME address or a range of
37            /// ESME addresses served via this `SMPP` session.
38            ///
39            /// Set to NULL if not known.
40            pub address_range: COctetString<1, 41>,
41        }
42
43        impl $name {
44            pub const fn new(
45                system_id: COctetString<1, 16>,
46                password: COctetString<1, 9>,
47                system_type: COctetString<1, 13>,
48                interface_version: InterfaceVersion,
49                addr_ton: Ton,
50                addr_npi: Npi,
51                address_range: COctetString<1, 41>,
52            ) -> Self {
53                Self {
54                    system_id,
55                    password,
56                    system_type,
57                    interface_version,
58                    addr_ton,
59                    addr_npi,
60                    address_range,
61                }
62            }
63
64            ::pastey::paste! {
65                pub fn builder() -> [<$name Builder>] {
66                    [<$name Builder>]::new()
67                }
68            }
69        }
70
71        ::pastey::paste! {
72            #[derive(Debug, Default)]
73            pub struct [<$name Builder>] {
74               inner: $name,
75            }
76
77            impl [<$name Builder>] {
78                pub fn new() -> Self {
79                    Self::default()
80                }
81
82                pub fn system_id(mut self, system_id: COctetString<1, 16>) -> Self {
83                    self.inner.system_id = system_id;
84                    self
85                }
86
87                pub fn password(mut self, password: COctetString<1, 9>) -> Self {
88                    self.inner.password = password;
89                    self
90                }
91
92                pub fn system_type(mut self, system_type: COctetString<1, 13>) -> Self {
93                    self.inner.system_type = system_type;
94                    self
95                }
96
97                pub const fn interface_version(mut self, interface_version: InterfaceVersion) -> Self {
98                    self.inner.interface_version = interface_version;
99                    self
100                }
101
102                pub const fn addr_ton(mut self, addr_ton: Ton) -> Self {
103                    self.inner.addr_ton = addr_ton;
104                    self
105                }
106
107                pub const fn addr_npi(mut self, addr_npi: Npi) -> Self {
108                    self.inner.addr_npi = addr_npi;
109                    self
110                }
111
112                pub fn address_range(mut self, address_range: COctetString<1, 41>) -> Self {
113                    self.inner.address_range = address_range;
114                    self
115                }
116
117                pub fn build(self) -> $name {
118                    self.inner
119                }
120            }
121        }
122    };
123}
124
125bind!(BindTransmitter);
126bind!(BindReceiver);
127bind!(BindTransceiver);
128bind!(BindAny);
129
130impl From<BindTransmitter> for Pdu {
131    fn from(value: BindTransmitter) -> Self {
132        Self::BindTransmitter(value)
133    }
134}
135
136impl From<BindReceiver> for Pdu {
137    fn from(value: BindReceiver) -> Self {
138        Self::BindReceiver(value)
139    }
140}
141
142impl From<BindTransceiver> for Pdu {
143    fn from(value: BindTransceiver) -> Self {
144        Self::BindTransceiver(value)
145    }
146}
147
148impl From<BindAny> for BindTransmitter {
149    fn from(value: BindAny) -> Self {
150        Self {
151            system_id: value.system_id,
152            password: value.password,
153            system_type: value.system_type,
154            interface_version: value.interface_version,
155            addr_ton: value.addr_ton,
156            addr_npi: value.addr_npi,
157            address_range: value.address_range,
158        }
159    }
160}
161
162impl From<BindAny> for BindReceiver {
163    fn from(value: BindAny) -> Self {
164        Self {
165            system_id: value.system_id,
166            password: value.password,
167            system_type: value.system_type,
168            interface_version: value.interface_version,
169            addr_ton: value.addr_ton,
170            addr_npi: value.addr_npi,
171            address_range: value.address_range,
172        }
173    }
174}
175
176impl From<BindAny> for BindTransceiver {
177    fn from(value: BindAny) -> Self {
178        Self {
179            system_id: value.system_id,
180            password: value.password,
181            system_type: value.system_type,
182            interface_version: value.interface_version,
183            addr_ton: value.addr_ton,
184            addr_npi: value.addr_npi,
185            address_range: value.address_range,
186        }
187    }
188}
189
190#[cfg(test)]
191mod tests {
192    use std::str::FromStr;
193
194    use crate::tests::TestInstance;
195
196    use super::*;
197
198    impl TestInstance for BindTransmitter {
199        fn instances() -> alloc::vec::Vec<Self> {
200            alloc::vec![
201                Self::default(),
202                Self::builder()
203                    .system_id(COctetString::from_str("system_id").unwrap())
204                    .password(COctetString::from_str("password").unwrap())
205                    .system_type(COctetString::from_str("system_type").unwrap())
206                    .interface_version(InterfaceVersion::Smpp5_0)
207                    .addr_ton(Ton::International)
208                    .addr_npi(Npi::Isdn)
209                    .address_range(COctetString::from_str("address_range").unwrap())
210                    .build(),
211            ]
212        }
213    }
214
215    impl TestInstance for BindReceiver {
216        fn instances() -> alloc::vec::Vec<Self> {
217            alloc::vec![
218                Self::default(),
219                Self::builder()
220                    .system_id(COctetString::from_str("system_id").unwrap())
221                    .password(COctetString::from_str("password").unwrap())
222                    .system_type(COctetString::from_str("system_type").unwrap())
223                    .interface_version(InterfaceVersion::Smpp3_4)
224                    .addr_ton(Ton::Alphanumeric)
225                    .addr_npi(Npi::Ermes)
226                    .address_range(COctetString::from_str("address_range").unwrap())
227                    .build(),
228            ]
229        }
230    }
231
232    impl TestInstance for BindTransceiver {
233        fn instances() -> alloc::vec::Vec<Self> {
234            alloc::vec![
235                Self::default(),
236                Self::builder()
237                    .system_id(COctetString::from_str("system_id").unwrap())
238                    .password(COctetString::from_str("password").unwrap())
239                    .system_type(COctetString::from_str("system_type").unwrap())
240                    .interface_version(InterfaceVersion::Smpp3_3OrEarlier(2))
241                    .addr_ton(Ton::International)
242                    .addr_npi(Npi::Ermes)
243                    .address_range(COctetString::from_str("address_range").unwrap())
244                    .build(),
245            ]
246        }
247    }
248
249    #[test]
250    fn encode_decode() {
251        crate::tests::owned::encode_decode_test_instances::<BindTransmitter>();
252        crate::tests::owned::encode_decode_test_instances::<BindReceiver>();
253        crate::tests::owned::encode_decode_test_instances::<BindTransceiver>();
254    }
255}