1use crate::TypeCodec;
2use mcproto_codec::{
3 error::{CodecError, CodecKind, CodecOperation, InvalidEncodingReason},
4 io::{read_exact_counted, write_all_counted},
5 varint::{VarIntRead, VarIntWrite},
6};
7use std::io::{Read, Write};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
11pub struct Boolean(pub bool);
12
13impl TypeCodec for Boolean {
14 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
15 let byte = if self.0 { 1u8 } else { 0u8 };
16 write_all_counted(writer, &[byte], CodecKind::Boolean, 0)
17 }
18
19 fn decode(reader: &mut impl Read) -> Result<Self, CodecError>
20 where
21 Self: Sized,
22 {
23 let mut buf = [0u8; 1];
24 read_exact_counted(reader, &mut buf, CodecKind::Boolean, 0)?;
25 match buf[0] {
26 0 => Ok(Boolean(false)),
27 1 => Ok(Boolean(true)),
28 _ => Err(CodecError::invalid_encoding(
29 CodecKind::Boolean,
30 1,
31 InvalidEncodingReason::InvalidBooleanValue { value: buf[0] },
32 )),
33 }
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
39pub struct Byte(pub i8);
40
41impl TypeCodec for Byte {
42 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
43 write_all_counted(writer, &self.0.to_be_bytes(), CodecKind::Byte, 0)
44 }
45
46 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
47 let mut bytes = [0; 1];
48 read_exact_counted(reader, &mut bytes, CodecKind::Byte, 0)?;
49 Ok(Self(i8::from_be_bytes(bytes)))
50 }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
55pub struct UnsignedByte(pub u8);
56
57impl TypeCodec for UnsignedByte {
58 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
59 write_all_counted(writer, &self.0.to_be_bytes(), CodecKind::UnsignedByte, 0)
60 }
61
62 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
63 let mut bytes = [0; 1];
64 read_exact_counted(reader, &mut bytes, CodecKind::UnsignedByte, 0)?;
65 Ok(Self(u8::from_be_bytes(bytes)))
66 }
67}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
71pub struct Short(pub i16);
72
73impl TypeCodec for Short {
74 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
75 write_all_counted(writer, &self.0.to_be_bytes(), CodecKind::Short, 0)
76 }
77
78 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
79 let mut bytes = [0; 2];
80 read_exact_counted(reader, &mut bytes, CodecKind::Short, 0)?;
81 Ok(Self(i16::from_be_bytes(bytes)))
82 }
83}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
87pub struct UnsignedShort(pub u16);
88
89impl TypeCodec for UnsignedShort {
90 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
91 write_all_counted(writer, &self.0.to_be_bytes(), CodecKind::UnsignedShort, 0)
92 }
93
94 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
95 let mut bytes = [0; 2];
96 read_exact_counted(reader, &mut bytes, CodecKind::UnsignedShort, 0)?;
97 Ok(Self(u16::from_be_bytes(bytes)))
98 }
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
103pub struct Int(pub i32);
104
105impl TypeCodec for Int {
106 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
107 write_all_counted(writer, &self.0.to_be_bytes(), CodecKind::Int, 0)
108 }
109
110 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
111 let mut bytes = [0; 4];
112 read_exact_counted(reader, &mut bytes, CodecKind::Int, 0)?;
113 Ok(Self(i32::from_be_bytes(bytes)))
114 }
115}
116
117#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
119pub struct Long(pub i64);
120
121impl TypeCodec for Long {
122 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
123 write_all_counted(writer, &self.0.to_be_bytes(), CodecKind::Long, 0)
124 }
125
126 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
127 let mut bytes = [0; 8];
128 read_exact_counted(reader, &mut bytes, CodecKind::Long, 0)?;
129 Ok(Self(i64::from_be_bytes(bytes)))
130 }
131}
132
133#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
135pub struct PrefixedString(pub String);
136
137impl PrefixedString {
138 pub const MAX_UTF16_CODE_UNITS: usize = 0x7fff;
139 pub const MAX_BYTES: usize = Self::MAX_UTF16_CODE_UNITS * 3;
140
141 fn validate_value(
142 value: &str,
143 operation: CodecOperation,
144 bytes_processed: usize,
145 ) -> Result<(), CodecError> {
146 let bytes = value.as_bytes();
147 if bytes.len() > Self::MAX_BYTES {
148 return Err(CodecError::invalid_encoding_for_operation(
149 CodecKind::String,
150 operation,
151 bytes_processed,
152 InvalidEncodingReason::StringTooLong {
153 max_bytes: Self::MAX_BYTES,
154 },
155 ));
156 }
157
158 if value.encode_utf16().count() > Self::MAX_UTF16_CODE_UNITS {
159 return Err(CodecError::invalid_encoding_for_operation(
160 CodecKind::String,
161 operation,
162 bytes_processed,
163 InvalidEncodingReason::TooManyUtf16CodeUnits {
164 max_code_units: Self::MAX_UTF16_CODE_UNITS,
165 },
166 ));
167 }
168
169 Ok(())
170 }
171
172 fn encode_value(value: &str, writer: &mut impl Write) -> Result<(), CodecError> {
173 Self::validate_value(value, CodecOperation::Write, 0)?;
174
175 let bytes = value.as_bytes();
176 let prefix_size = writer
177 .write_varint_with_size(bytes.len() as i32)
178 .map_err(|error| error.with_context(CodecKind::String))?;
179 write_all_counted(writer, bytes, CodecKind::String, prefix_size)
180 }
181}
182
183impl TypeCodec for PrefixedString {
184 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
185 Self::encode_value(&self.0, writer)
186 }
187
188 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
189 let (byte_length, prefix_size) = reader
190 .read_varint_with_size()
191 .map_err(|error| error.with_context(CodecKind::String))?;
192 let byte_length = usize::try_from(byte_length).map_err(|_| {
193 CodecError::invalid_encoding(
194 CodecKind::String,
195 prefix_size,
196 InvalidEncodingReason::NegativeLength { value: byte_length },
197 )
198 })?;
199
200 if byte_length > Self::MAX_BYTES {
201 return Err(CodecError::invalid_encoding(
202 CodecKind::String,
203 prefix_size,
204 InvalidEncodingReason::StringTooLong {
205 max_bytes: Self::MAX_BYTES,
206 },
207 ));
208 }
209
210 let mut bytes = vec![0; byte_length];
211 read_exact_counted(reader, &mut bytes, CodecKind::String, prefix_size)?;
212
213 let value = String::from_utf8(bytes).map_err(|error| {
214 let utf8_error = error.utf8_error();
215 CodecError::invalid_encoding(
216 CodecKind::String,
217 prefix_size + byte_length,
218 InvalidEncodingReason::InvalidUtf8 {
219 valid_up_to: utf8_error.valid_up_to(),
220 error_len: utf8_error.error_len(),
221 },
222 )
223 })?;
224 Self::validate_value(&value, CodecOperation::Read, prefix_size + byte_length)?;
225 Ok(Self(value))
226 }
227}
228
229#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
231pub struct Identifier(pub String);
232
233impl Identifier {
234 pub const MAX_UTF16_CODE_UNITS: usize = PrefixedString::MAX_UTF16_CODE_UNITS;
235 pub const MAX_BYTES: usize = PrefixedString::MAX_BYTES;
236 pub const MAX_ENCODED_BYTES: usize = Self::MAX_BYTES + 3;
237}
238
239impl TypeCodec for Identifier {
240 fn encode(&self, writer: &mut impl Write) -> Result<(), CodecError> {
241 PrefixedString::encode_value(&self.0, writer)
242 .map_err(|error| error.with_context(CodecKind::Identifier))
243 }
244
245 fn decode(reader: &mut impl Read) -> Result<Self, CodecError> {
246 PrefixedString::decode(reader)
247 .map(|value| Self(value.0))
248 .map_err(|error| error.with_context(CodecKind::Identifier))
249 }
250}