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