1use rusmpp_macros::Rusmpp;
2
3#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
4#[rusmpp(repr = "u8", test = skip)]
5#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
6#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
7#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
8pub struct EsmClass {
9 pub messaging_mode: MessagingMode,
10 pub message_type: MessageType,
11 pub ansi41_specific: Ansi41Specific,
12 pub gsm_features: GsmFeatures,
13}
14
15impl EsmClass {
16 pub fn new(
17 messaging_mode: MessagingMode,
18 message_type: MessageType,
19 ansi41_specific: Ansi41Specific,
20 gsm_features: GsmFeatures,
21 ) -> Self {
22 Self {
23 messaging_mode,
24 message_type,
25 ansi41_specific,
26 gsm_features,
27 }
28 }
29}
30
31impl From<u8> for EsmClass {
32 fn from(value: u8) -> Self {
33 Self {
34 messaging_mode: MessagingMode::from(value & 0b00_00_00_11),
35 message_type: MessageType::from(value & 0b00_10_01_00),
36 ansi41_specific: Ansi41Specific::from(value & 0b00_01_10_00),
37 gsm_features: GsmFeatures::from(value & 0b11_00_00_00),
38 }
39 }
40}
41
42impl From<EsmClass> for u8 {
43 fn from(value: EsmClass) -> Self {
44 u8::from(value.messaging_mode)
45 | u8::from(value.message_type)
46 | u8::from(value.ansi41_specific)
47 | u8::from(value.gsm_features)
48 }
49}
50
51#[repr(u8)]
52#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
53#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
54#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
55#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
56pub enum MessagingMode {
57 #[default]
58 Default = 0b00_00_00_00,
59 Datagram = 0b00_00_00_01,
60 Forward = 0b00_00_00_10,
61 StoreAndForward = 0b00_00_00_11,
62 Other(u8),
63}
64
65#[repr(u8)]
66#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
67#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
68#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
69#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
70pub enum MessageType {
71 #[default]
72 Default = 0b00_00_00_00,
73 ShortMessageContainsMCDeliveryReceipt = 0b00_00_01_00,
74 ShortMessageContainsIntermediateDeliveryNotification = 0b00_10_00_00,
75 Other(u8),
76}
77
78#[repr(u8)]
79#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
80#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
81#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
82#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
83pub enum Ansi41Specific {
84 #[default]
85 ShortMessageContainsDeliveryAcknowledgement = 0b00_00_10_00,
86 ShortMessageContainsUserAcknowledgment = 0b00_01_00_00,
87 ShortMessageContainsConversationAbort = 0b00_01_10_00,
88 Other(u8),
89}
90
91#[repr(u8)]
92#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
93#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
94#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
95#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
96pub enum GsmFeatures {
97 #[default]
98 NotSelected = 0b00_00_00_00,
99 UdhiIndicator = 0b01_00_00_00,
100 SetReplyPath = 0b10_00_00_00,
101 SetUdhiAndReplyPath = 0b11_00_00_00,
102 Other(u8),
103}
104
105#[cfg(test)]
106mod tests {
107 use crate::tests::TestInstance;
108
109 use super::*;
110
111 impl TestInstance for EsmClass {
112 fn instances() -> alloc::vec::Vec<Self> {
113 alloc::vec![
114 Self::default(),
115 Self::new(
116 MessagingMode::Forward,
117 MessageType::ShortMessageContainsIntermediateDeliveryNotification,
118 Ansi41Specific::ShortMessageContainsConversationAbort,
119 GsmFeatures::UdhiIndicator,
120 ),
121 Self::new(
122 MessagingMode::Datagram,
123 MessageType::ShortMessageContainsMCDeliveryReceipt,
124 Ansi41Specific::ShortMessageContainsUserAcknowledgment,
125 GsmFeatures::UdhiIndicator,
126 ),
127 ]
128 }
129 }
130
131 #[test]
132 fn encode_decode() {
133 crate::tests::owned::encode_decode_test_instances::<EsmClass>();
134 crate::tests::borrowed::encode_decode_test_instances::<EsmClass>();
135
136 crate::tests::owned::encode_decode_test_instances::<MessagingMode>();
137 crate::tests::borrowed::encode_decode_test_instances::<MessagingMode>();
138
139 crate::tests::owned::encode_decode_test_instances::<MessageType>();
140 crate::tests::borrowed::encode_decode_test_instances::<MessageType>();
141
142 crate::tests::owned::encode_decode_test_instances::<Ansi41Specific>();
143 crate::tests::borrowed::encode_decode_test_instances::<GsmFeatures>();
144 }
145}