luanti_protocol/wire/
deser.rs1use crate::types::CommandDirection;
2use crate::types::ProtocolContext;
3use anyhow::bail;
4use std::fmt::Debug;
5use std::num::ParseIntError;
6use std::str::Utf8Error;
7
8#[derive(Debug, thiserror::Error)]
9pub enum DeserializeError {
10 #[error("Bad Packet Type {0:?} type={1}")]
11 BadPacketId(CommandDirection, u16),
12 #[error("Invalid value: {0}")]
13 InvalidValue(String),
14 #[error("Invalid Protocol id: {0}")]
15 InvalidProtocolId(u32),
16 #[error("Invalid channel: {0}")]
17 InvalidChannel(u8),
18 #[error("Invalid Packet Kind: {0}")]
19 InvalidPacketKind(u8),
20 #[error("DecompressionFailed: {0}")]
21 DecompressionFailed(String),
22 #[error("OtherError: {0}")]
23 OtherError(String),
24 #[error("EOF during deserialization: {0}")]
25 Eof(String), }
27
28impl From<Utf8Error> for DeserializeError {
29 fn from(other: Utf8Error) -> DeserializeError {
30 DeserializeError::InvalidValue(format!("Utf8Error {other:?}"))
31 }
32}
33
34impl From<ParseIntError> for DeserializeError {
35 fn from(other: ParseIntError) -> DeserializeError {
36 DeserializeError::InvalidValue(format!("ParseIntError {other:?}"))
37 }
38}
39
40impl From<anyhow::Error> for DeserializeError {
41 fn from(value: anyhow::Error) -> Self {
42 DeserializeError::OtherError(format!("OtherError {value:?}"))
43 }
44}
45
46pub type DeserializeResult<R> = anyhow::Result<R>;
47
48pub struct Deserializer<'data> {
49 pub context: ProtocolContext,
50 pub data: &'data [u8], }
52
53impl<'data> Deserializer<'data> {
54 #[must_use]
55 pub fn new(context: ProtocolContext, data: &'data [u8]) -> Self {
56 Self { context, data }
57 }
58
59 pub fn slice(&mut self, count: usize) -> DeserializeResult<Self> {
62 Ok(Self {
63 context: self.context,
64 data: self.take(count)?,
65 })
66 }
67
68 #[must_use]
69 pub fn context(&self) -> ProtocolContext {
70 self.context
71 }
72
73 #[must_use]
74 pub fn direction(&self) -> CommandDirection {
75 self.context.dir
76 }
77
78 #[must_use]
80 pub fn has_remaining(&self) -> bool {
81 self.remaining() > 0
82 }
83
84 #[must_use]
85 pub fn remaining(&self) -> usize {
86 self.data.len()
87 }
88
89 pub fn find(&mut self, byte: u8) -> Option<usize> {
92 self.data.iter().position(|ch| *ch == byte)
93 }
94
95 pub fn peek(&mut self, count: usize) -> DeserializeResult<&'data [u8]> {
96 if count > self.data.len() {
97 bail!(DeserializeError::Eof(format!(
98 "Deserializer::peek({count})"
99 )))
100 }
101 Ok(&self.data[0..count])
102 }
103
104 pub fn peek_all(&mut self) -> &'data [u8] {
105 self.data
106 }
107
108 pub fn take(&mut self, count: usize) -> DeserializeResult<&'data [u8]> {
109 if count > self.data.len() {
110 bail!(DeserializeError::Eof(format!(
111 "Deserializer::take({count})"
112 )))
113 }
114 let (ret, data) = self.data.split_at(count);
115 self.data = data;
116 Ok(ret)
117 }
118
119 pub fn take_n<const N: usize>(&mut self) -> DeserializeResult<[u8; N]> {
120 Ok(self.take(N)?.try_into().unwrap())
121 }
122
123 pub fn take_all(&mut self) -> &'data [u8] {
124 let (ret, data) = self.data.split_at(self.data.len());
125 self.data = data;
126 ret
127 }
128
129 pub fn peek_line(&mut self) -> DeserializeResult<&'data [u8]> {
132 let line_len = match self.find(b'\n') {
133 Some(pos) => pos + 1,
134 None => self.remaining(),
135 };
136 self.peek(line_len)
137 }
138
139 pub fn take_line(&mut self) -> DeserializeResult<&'data [u8]> {
142 let line_len = match self.find(b'\n') {
143 Some(pos) => pos + 1,
144 None => self.remaining(),
145 };
146 self.take(line_len)
147 }
148
149 pub fn take_word(&mut self, skip_whitespace: bool) -> &'data [u8] {
154 if skip_whitespace {
155 self.take_space();
156 }
157 match self.data.iter().position(|&ch| ch == b' ' || ch == b'\n') {
158 Some(end) => {
159 let (ret, data) = self.data.split_at(end);
160 self.data = data;
161 ret
162 }
163 None => self.take_all(),
164 }
165 }
166
167 pub fn take_space(&mut self) {
170 match self.data.iter().position(|&ch| ch != b' ' && ch != b'\n') {
171 Some(pos) => {
172 (_, self.data) = self.data.split_at(pos);
173 }
174 None => {
175 self.take_all();
176 }
177 };
178 }
179}
180
181pub trait Deserialize: Sized + Debug {
182 type Output;
184 fn deserialize(deserializer: &mut Deserializer<'_>) -> DeserializeResult<Self::Output>;
185}