rusmpp_core/command/
borrowed.rs1use rusmpp_macros::Rusmpp;
2
3use crate::{CommandId, CommandStatus, pdus::borrowed::Pdu};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
39#[rusmpp(decode = borrowed)]
40#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
41#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
42pub struct Command<'a, const N: usize> {
43 id: CommandId,
45 pub status: CommandStatus,
47 pub sequence_number: u32,
51 #[rusmpp(key = id, length = "unchecked")]
55 pdu: Option<Pdu<'a, N>>,
56}
57
58impl<'a, const N: usize> Default for Command<'a, N> {
59 fn default() -> Self {
60 Self {
61 id: CommandId::EnquireLink,
62 status: CommandStatus::EsmeRok,
63 sequence_number: 0,
64 pdu: Some(Pdu::EnquireLink),
65 }
66 }
67}
68
69impl<'a, const N: usize> Command<'a, N> {
70 pub fn new(status: CommandStatus, sequence_number: u32, pdu: impl Into<Pdu<'a, N>>) -> Self {
71 Self::new_const(status, sequence_number, pdu.into())
72 }
73
74 pub const fn new_const(status: CommandStatus, sequence_number: u32, pdu: Pdu<'a, N>) -> Self {
75 let id = pdu.command_id();
76
77 Self {
78 id,
79 status,
80 sequence_number,
81 pdu: Some(pdu),
82 }
83 }
84
85 #[inline]
86 pub const fn id(&self) -> CommandId {
87 self.id
88 }
89
90 #[inline]
91 pub const fn status(&self) -> CommandStatus {
92 self.status
93 }
94
95 #[inline]
96 pub const fn sequence_number(&self) -> u32 {
97 self.sequence_number
98 }
99
100 #[inline]
101 pub const fn pdu(&self) -> Option<&Pdu<'a, N>> {
102 self.pdu.as_ref()
103 }
104
105 #[inline]
106 pub fn set_pdu(&mut self, pdu: impl Into<Pdu<'a, N>>) {
107 let pdu = pdu.into();
108
109 self.id = pdu.command_id();
110
111 self.pdu = Some(pdu);
112 }
113
114 #[inline]
115 pub fn builder() -> CommandStatusBuilder<'a, N> {
116 Default::default()
117 }
118}
119
120#[derive(Debug, Default)]
121pub struct CommandStatusBuilder<'a, const N: usize> {
122 inner: Command<'a, N>,
123}
124
125impl<'a, const N: usize> CommandStatusBuilder<'a, N> {
126 #[inline]
127 pub fn status(mut self, status: CommandStatus) -> SequenceNumberBuilder<'a, N> {
128 self.inner.status = status;
129
130 SequenceNumberBuilder { inner: self.inner }
131 }
132}
133
134#[derive(Debug)]
135pub struct SequenceNumberBuilder<'a, const N: usize> {
136 inner: Command<'a, N>,
137}
138
139impl<'a, const N: usize> SequenceNumberBuilder<'a, N> {
140 #[inline]
141 pub fn sequence_number(mut self, sequence_number: u32) -> PduBuilder<'a, N> {
142 self.inner.sequence_number = sequence_number;
143
144 PduBuilder { inner: self.inner }
145 }
146}
147
148#[derive(Debug)]
149pub struct PduBuilder<'a, const N: usize> {
150 inner: Command<'a, N>,
151}
152
153impl<'a, const N: usize> PduBuilder<'a, N> {
154 #[inline]
155 pub fn pdu(mut self, pdu: impl Into<Pdu<'a, N>>) -> Command<'a, N> {
156 self.inner.set_pdu(pdu);
157 self.inner
158 }
159}
160
161#[cfg(test)]
162mod tests {
163 use super::*;
164
165 #[test]
166 fn encode_decode() {
167 crate::tests::borrowed::encode_decode_with_length_test_instances::<Command<'static, 16>>();
168 }
169}