loco_protocol/command/
mod.rs1use core::{fmt::Debug, ops::Deref};
8
9use alloc::boxed::Box;
10use serde::{
11 de::{self, Unexpected, Visitor},
12 Deserialize, Serialize,
13};
14
15pub mod client;
16
17#[derive(Clone, PartialEq, Eq)]
18pub struct Method {
20 len: usize,
21 buf: [u8; 11],
22}
23
24impl Method {
25 pub fn new(string: &str) -> Option<Self> {
29 let bytes = string.as_bytes();
30 let len = bytes.len();
31 if len > 11 {
32 return None;
33 }
34
35 let mut buf = [0_u8; 11];
36 buf[..len].copy_from_slice(bytes);
37
38 Some(Self { len, buf })
39 }
40
41 pub const fn is_empty(&self) -> bool {
42 self.len == 0
43 }
44
45 pub const fn len(&self) -> usize {
46 self.len
47 }
48}
49
50impl Debug for Method {
51 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
52 f.debug_tuple("Method").field(&self.deref()).finish()
53 }
54}
55
56impl Deref for Method {
57 type Target = str;
58
59 fn deref(&self) -> &Self::Target {
60 core::str::from_utf8(&self.buf[..self.len]).unwrap()
61 }
62}
63
64impl Serialize for Method {
65 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
66 where
67 S: serde::Serializer,
68 {
69 serializer.serialize_newtype_struct("Method", &self.buf)
70 }
71}
72
73impl<'de> Deserialize<'de> for Method {
74 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
75 where
76 D: serde::Deserializer<'de>,
77 {
78 struct MethodVisitor;
79
80 impl<'a> Visitor<'a> for MethodVisitor {
81 type Value = Method;
82
83 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
84 write!(formatter, "utf-8 byte array that has 11 length")
85 }
86
87 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
88 where
89 D: serde::Deserializer<'a>,
90 {
91 deserializer.deserialize_tuple(11, MethodVisitor)
92 }
93
94 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
95 where
96 A: serde::de::SeqAccess<'a>,
97 {
98 let mut buf = [0_u8; 11];
99
100 for item in &mut buf {
101 *item = seq.next_element::<u8>()?.ok_or(de::Error::invalid_length(
102 11,
103 &"an array of size 11 was expected",
104 ))?;
105 }
106
107 let len = core::str::from_utf8(&buf)
108 .map_err(|_| {
109 de::Error::invalid_type(
110 Unexpected::Bytes(&buf),
111 &"a valid utf-8 array was expected",
112 )
113 })?
114 .trim_matches(char::from(0))
115 .len();
116
117 Ok(Method { len, buf })
118 }
119 }
120
121 deserializer.deserialize_newtype_struct("Method", MethodVisitor)
122 }
123}
124
125#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
126pub struct Header {
127 pub id: u32,
128 pub status: u16,
129 pub method: Method,
130 pub data_type: u8,
131}
132
133#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
134pub struct Command<T: ?Sized> {
135 pub header: Header,
136 pub data: T,
137}
138
139pub type BoxedCommand = Command<Box<[u8]>>;