1use rusmpp_macros::Rusmpp;
2
3#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
11#[rusmpp(repr = "u8", 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 EsmClass {
16 pub messaging_mode: MessagingMode,
18 pub message_type: MessageType,
20 pub ansi41_specific: Ansi41Specific,
22 pub gsm_features: GsmFeatures,
24}
25
26impl EsmClass {
27 pub fn new(
28 messaging_mode: MessagingMode,
29 message_type: MessageType,
30 ansi41_specific: Ansi41Specific,
31 gsm_features: GsmFeatures,
32 ) -> Self {
33 Self {
34 messaging_mode,
35 message_type,
36 ansi41_specific,
37 gsm_features,
38 }
39 }
40
41 pub const fn with_udhi_indicator(self) -> Self {
43 Self {
44 messaging_mode: self.messaging_mode,
45 message_type: self.message_type,
46 ansi41_specific: self.ansi41_specific,
47 gsm_features: GsmFeatures::UdhiIndicator,
48 }
49 }
50}
51
52impl From<u8> for EsmClass {
53 fn from(value: u8) -> Self {
54 Self {
55 messaging_mode: MessagingMode::from(value & 0b00_00_00_11),
56 message_type: MessageType::from(value & 0b00_10_01_00),
57 ansi41_specific: Ansi41Specific::from(value & 0b00_01_10_00),
58 gsm_features: GsmFeatures::from(value & 0b11_00_00_00),
59 }
60 }
61}
62
63impl From<EsmClass> for u8 {
64 fn from(value: EsmClass) -> Self {
65 u8::from(value.messaging_mode)
66 | u8::from(value.message_type)
67 | u8::from(value.ansi41_specific)
68 | u8::from(value.gsm_features)
69 }
70}
71
72#[repr(u8)]
74#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
75#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
76#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
77#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
78pub enum MessagingMode {
79 #[default]
81 Default = 0b00_00_00_00,
82 Datagram = 0b00_00_00_01,
84 Forward = 0b00_00_00_10,
86 StoreAndForward = 0b00_00_00_11,
91 Other(u8),
92}
93
94#[repr(u8)]
96#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
97#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
98#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
99#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
100pub enum MessageType {
101 #[default]
103 Default = 0b00_00_00_00,
104 ShortMessageContainsMCDeliveryReceipt = 0b00_00_01_00,
106 ShortMessageContainsIntermediateDeliveryNotification = 0b00_10_00_00,
108 Other(u8),
109}
110
111#[repr(u8)]
113#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
114#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
115#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
116#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
117pub enum Ansi41Specific {
118 #[default]
120 ShortMessageContainsDeliveryAcknowledgement = 0b00_00_10_00,
121 ShortMessageContainsUserAcknowledgment = 0b00_01_00_00,
123 ShortMessageContainsConversationAbort = 0b00_01_10_00,
125 Other(u8),
126}
127
128#[repr(u8)]
130#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
131#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
132#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
133#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
134pub enum GsmFeatures {
135 #[default]
137 NotSelected = 0b00_00_00_00,
138 UdhiIndicator = 0b01_00_00_00,
140 SetReplyPath = 0b10_00_00_00,
142 SetUdhiAndReplyPath = 0b11_00_00_00,
144 Other(u8),
145}
146
147#[cfg(test)]
148mod tests {
149 use crate::tests::TestInstance;
150
151 use super::*;
152
153 impl TestInstance for EsmClass {
154 fn instances() -> alloc::vec::Vec<Self> {
155 alloc::vec![
156 Self::default(),
157 Self::new(
158 MessagingMode::Forward,
159 MessageType::ShortMessageContainsIntermediateDeliveryNotification,
160 Ansi41Specific::ShortMessageContainsConversationAbort,
161 GsmFeatures::UdhiIndicator,
162 ),
163 Self::new(
164 MessagingMode::Datagram,
165 MessageType::ShortMessageContainsMCDeliveryReceipt,
166 Ansi41Specific::ShortMessageContainsUserAcknowledgment,
167 GsmFeatures::UdhiIndicator,
168 ),
169 ]
170 }
171 }
172
173 #[test]
174 fn encode_decode() {
175 #[cfg(feature = "alloc")]
176 crate::tests::owned::encode_decode_test_instances::<EsmClass>();
177 crate::tests::borrowed::encode_decode_test_instances::<EsmClass>();
178 #[cfg(feature = "alloc")]
179 crate::tests::owned::encode_decode_test_instances::<MessagingMode>();
180 crate::tests::borrowed::encode_decode_test_instances::<MessagingMode>();
181 #[cfg(feature = "alloc")]
182 crate::tests::owned::encode_decode_test_instances::<MessageType>();
183 crate::tests::borrowed::encode_decode_test_instances::<MessageType>();
184 #[cfg(feature = "alloc")]
185 crate::tests::owned::encode_decode_test_instances::<Ansi41Specific>();
186 crate::tests::borrowed::encode_decode_test_instances::<GsmFeatures>();
187 }
188}