rusmpp_core/values/dest_address/
owned.rs

1use rusmpp_macros::Rusmpp;
2
3use crate::{
4    decode::{
5        DecodeError, DecodeResultExt,
6        owned::{Decode, DecodeExt},
7    },
8    encode::Length,
9    types::owned::COctetString,
10    values::{dest_address::DestFlag, npi::Npi, ton::Ton},
11};
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
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))]
17pub enum DestAddress {
18    /// SME Format Destination Address.
19    SmeAddress(SmeAddress),
20    /// Distribution List Format Destination Address.
21    DistributionListName(DistributionListName),
22}
23
24impl Length for DestAddress {
25    fn length(&self) -> usize {
26        match self {
27            Self::SmeAddress(sa) => sa.length(),
28            Self::DistributionListName(dlm) => dlm.length(),
29        }
30    }
31}
32
33impl crate::encode::Encode for DestAddress {
34    fn encode(&self, dst: &mut [u8]) -> usize {
35        match self {
36            Self::SmeAddress(sa) => sa.encode(dst),
37            Self::DistributionListName(dlm) => dlm.encode(dst),
38        }
39    }
40}
41
42impl crate::encode::owned::Encode for DestAddress {
43    fn encode(&self, dst: &mut bytes::BytesMut) {
44        match self {
45            Self::SmeAddress(sa) => sa.encode(dst),
46            Self::DistributionListName(dlm) => dlm.encode(dst),
47        }
48    }
49}
50
51impl Decode for DestAddress {
52    fn decode(src: &mut bytes::BytesMut) -> Result<(Self, usize), DecodeError> {
53        let size = 0;
54
55        let (flag, size) = DestFlag::decode_move(src, size)?;
56
57        match flag {
58            DestFlag::SmeAddress => {
59                SmeAddress::decode_move(src, size).map_decoded(Self::SmeAddress)
60            }
61            DestFlag::DistributionListName => {
62                DistributionListName::decode_move(src, size).map_decoded(Self::DistributionListName)
63            }
64            DestFlag::Other(flag) => Err(DecodeError::unsupported_key(flag.into())),
65        }
66    }
67}
68
69/// SME Format Destination Address.
70#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
71#[rusmpp(decode = owned, test = skip)]
72#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
73#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
74#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
75pub struct SmeAddress {
76    /// 0x01 (SME Address).
77    ///
78    /// Can't and shouldn't be updated
79    #[rusmpp(skip_decode)]
80    dest_flag: DestFlag,
81    /// Type of Number for destination.
82    pub dest_addr_ton: Ton,
83    /// Numbering Plan Indicator for destination.
84    pub dest_addr_npi: Npi,
85    /// Destination address of this short message. For mobile
86    /// terminated messages, this is the directory number of the
87    /// recipient MS.
88    pub destination_addr: COctetString<1, 21>,
89}
90
91impl SmeAddress {
92    pub const fn new(
93        dest_addr_ton: Ton,
94        dest_addr_npi: Npi,
95        destination_addr: COctetString<1, 21>,
96    ) -> Self {
97        Self {
98            dest_flag: DestFlag::SmeAddress,
99            dest_addr_ton,
100            dest_addr_npi,
101            destination_addr,
102        }
103    }
104
105    pub fn dest_flag(&self) -> DestFlag {
106        self.dest_flag
107    }
108}
109
110/// Distribution List Format Destination Address.
111#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
112#[rusmpp(decode = owned, test = skip)]
113#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
114#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
115#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
116pub struct DistributionListName {
117    /// 0x02 (Distribution List).
118    ///
119    /// Can't and shouldn't be updated.
120    #[rusmpp(skip_decode)]
121    dest_flag: DestFlag,
122    /// Name of Distribution List.
123    pub dl_name: COctetString<1, 21>,
124}
125
126impl DistributionListName {
127    pub fn new(dl_name: COctetString<1, 21>) -> Self {
128        Self {
129            dest_flag: DestFlag::DistributionListName,
130            dl_name,
131        }
132    }
133
134    pub fn dest_flag(&self) -> DestFlag {
135        self.dest_flag
136    }
137}
138
139#[cfg(test)]
140mod tests {
141    //! See tests in [borrowed](super::super::borrowed) for more details.
142
143    use super::*;
144
145    impl crate::tests::TestInstance for DestAddress {
146        fn instances() -> alloc::vec::Vec<Self> {
147            alloc::vec![
148                Self::SmeAddress(SmeAddress::new(
149                    Ton::International,
150                    Npi::Isdn,
151                    COctetString::from_static_slice(b"1234567890123456789\0").unwrap(),
152                )),
153                Self::DistributionListName(DistributionListName::new(
154                    COctetString::from_static_slice(b"1234567890123456789\0").unwrap(),
155                )),
156            ]
157        }
158    }
159
160    #[test]
161    fn encode_decode() {
162        crate::tests::owned::encode_decode_test_instances::<DestAddress>();
163    }
164}