1use std::{
2 collections::HashMap,
3 hash::Hash,
4 io::{self, Cursor, Write},
5 sync::Arc,
6};
7
8use indexmap::IndexMap;
9
10use crate::{
11 AzBuf, AzBufLimited, AzBufVar, BufReadError, MAX_STRING_LENGTH, UnsizedByteArray, read_bytes,
12 read_utf_with_len, write_utf_with_len,
13};
14
15impl AzBuf for UnsizedByteArray {
16 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
17 let data = buf.get_ref()[buf.position() as usize..].to_vec();
19 buf.set_position((buf.position()) + data.len() as u64);
20 Ok(UnsizedByteArray(data))
21 }
22 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
23 buf.write_all(self)
24 }
25}
26
27macro_rules! impl_for_map_type {
28 ($ty: ident) => {
29 impl<K: AzBuf + Eq + Hash, V: AzBuf> AzBuf for $ty<K, V> {
30 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
31 let length = i32::azalea_read_var(buf)? as usize;
32 let mut contents = Self::with_capacity(usize::min(length, 65536));
33 for _ in 0..length {
34 contents.insert(K::azalea_read(buf)?, V::azalea_read(buf)?);
35 }
36 Ok(contents)
37 }
38 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
39 u32::azalea_write_var(&(self.len() as u32), buf)?;
40 for (key, value) in self {
41 key.azalea_write(buf)?;
42 value.azalea_write(buf)?;
43 }
44
45 Ok(())
46 }
47 }
48 impl<K: AzBuf + Eq + Hash, V: AzBufVar> AzBufVar for $ty<K, V> {
49 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
50 let length = i32::azalea_read_var(buf)? as usize;
51 let mut contents = Self::with_capacity(usize::min(length, 65536));
52 for _ in 0..length {
53 contents.insert(K::azalea_read(buf)?, V::azalea_read_var(buf)?);
54 }
55 Ok(contents)
56 }
57 fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> {
58 u32::azalea_write_var(&(self.len() as u32), buf)?;
59 for (key, value) in self {
60 key.azalea_write(buf)?;
61 value.azalea_write_var(buf)?;
62 }
63
64 Ok(())
65 }
66 }
67 };
68}
69
70impl_for_map_type!(HashMap);
71impl_for_map_type!(IndexMap);
72
73macro_rules! impl_for_list_type {
74 ($ty: ty) => {
75 impl<T: AzBuf> AzBuf for $ty {
76 default fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
77 let length = u32::azalea_read_var(buf)? as usize;
78 let mut contents = Vec::with_capacity(usize::min(length, 65536));
80 for _ in 0..length {
81 contents.push(T::azalea_read(buf)?);
82 }
83 Ok(contents.into())
84 }
85 default fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
86 (self.len() as u32).azalea_write_var(buf)?;
87 for item in self {
88 T::azalea_write(item, buf)?;
89 }
90 Ok(())
91 }
92 }
93 impl<T: AzBufVar> AzBufVar for $ty {
94 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
95 let length = i32::azalea_read_var(buf)? as usize;
96 let mut contents = Vec::with_capacity(usize::min(length, 65536));
97 for _ in 0..length {
98 contents.push(T::azalea_read_var(buf)?);
99 }
100 Ok(contents.into())
101 }
102 fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> {
103 (self.len() as u32).azalea_write_var(buf)?;
104 for item in self {
105 T::azalea_write_var(item, buf)?;
106 }
107 Ok(())
108 }
109 }
110 impl<T: AzBuf> AzBufLimited for $ty {
111 fn azalea_read_limited(
112 buf: &mut Cursor<&[u8]>,
113 limit: u32,
114 ) -> Result<Self, BufReadError> {
115 let length = u32::azalea_read_var(buf)?;
116 if length > limit {
117 return Err(BufReadError::VecLengthTooLong {
118 length: length as u32,
119 max_length: limit as u32,
120 });
121 }
122
123 let mut contents = Vec::with_capacity(u32::min(length, 65536) as usize);
124 for _ in 0..length {
125 contents.push(T::azalea_read(buf)?);
126 }
127 Ok(contents.into())
128 }
129 }
130 };
131}
132
133impl_for_list_type!(Vec<T>);
134impl_for_list_type!(Box<[T]>);
135
136impl AzBuf for Vec<u8> {
137 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
138 let length = i32::azalea_read_var(buf)? as usize;
139 read_bytes(buf, length).map(|b| b.to_vec())
140 }
141 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
142 (self.len() as u32).azalea_write_var(buf)?;
143 buf.write_all(self)
144 }
145}
146
147impl AzBuf for String {
148 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
149 read_utf_with_len(buf, MAX_STRING_LENGTH).map(Into::into)
150 }
151 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
152 write_utf_with_len(buf, self, MAX_STRING_LENGTH)
153 }
154}
155impl AzBufLimited for String {
156 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: u32) -> Result<Self, BufReadError> {
157 read_utf_with_len(buf, limit).map(Into::into)
158 }
159}
160
161impl AzBuf for Box<str> {
162 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
163 read_utf_with_len(buf, MAX_STRING_LENGTH).map(Into::into)
164 }
165 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
166 write_utf_with_len(buf, self, MAX_STRING_LENGTH)
167 }
168}
169
170impl AzBufLimited for Box<str> {
171 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: u32) -> Result<Self, BufReadError> {
172 String::azalea_read_limited(buf, limit).map(Into::into)
173 }
174}
175
176impl<T: AzBuf> AzBuf for Option<T> {
177 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
178 let present = bool::azalea_read(buf)?;
179 Ok(if present {
180 Some(T::azalea_read(buf)?)
181 } else {
182 None
183 })
184 }
185 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
186 if let Some(s) = self {
187 true.azalea_write(buf)?;
188 s.azalea_write(buf)?;
189 } else {
190 false.azalea_write(buf)?;
191 };
192 Ok(())
193 }
194}
195
196impl<T: AzBufVar> AzBufVar for Option<T> {
197 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
198 let present = bool::azalea_read(buf)?;
199 Ok(if present {
200 Some(T::azalea_read_var(buf)?)
201 } else {
202 None
203 })
204 }
205 fn azalea_write_var(&self, buf: &mut impl Write) -> io::Result<()> {
206 if let Some(s) = self {
207 true.azalea_write(buf)?;
208 s.azalea_write_var(buf)?;
209 } else {
210 false.azalea_write(buf)?;
211 };
212 Ok(())
213 }
214}
215impl<T: AzBufLimited> AzBufLimited for Option<T> {
216 fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: u32) -> Result<Self, BufReadError> {
217 let present = bool::azalea_read(buf)?;
218 Ok(if present {
219 Some(T::azalea_read_limited(buf, limit)?)
220 } else {
221 None
222 })
223 }
224}
225
226impl<T: AzBuf, const N: usize> AzBuf for [T; N] {
227 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
228 let mut contents = Vec::with_capacity(N);
229 for _ in 0..N {
230 contents.push(T::azalea_read(buf)?);
231 }
232 Ok(contents
233 .try_into()
234 .unwrap_or_else(|_| unreachable!("The vec is the same size as the array")))
235 }
236 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
237 for i in self {
238 i.azalea_write(buf)?;
239 }
240 Ok(())
241 }
242}
243
244impl AzBuf for simdnbt::owned::NbtTag {
245 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
246 Ok(simdnbt::owned::read_tag(buf).map_err(simdnbt::Error::from)?)
247 }
248 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
249 let mut data = Vec::new();
250 self.write(&mut data);
251 buf.write_all(&data)
252 }
253}
254
255impl AzBuf for simdnbt::owned::NbtCompound {
256 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
257 match simdnbt::owned::read_tag(buf).map_err(simdnbt::Error::from)? {
258 simdnbt::owned::NbtTag::Compound(compound) => Ok(compound),
259 _ => Err(BufReadError::Custom("Expected compound tag".to_owned())),
260 }
261 }
262 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
263 let mut data = Vec::new();
264 simdnbt::owned::NbtTag::Compound(self.clone()).write(&mut data);
265 buf.write_all(&data)
266 }
267}
268
269impl AzBuf for simdnbt::owned::Nbt {
270 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
271 Ok(simdnbt::owned::read_unnamed(buf)?)
272 }
273 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
274 let mut data = Vec::new();
275 self.write_unnamed(&mut data);
276 buf.write_all(&data)
277 }
278}
279
280impl<T> AzBuf for Box<T>
281where
282 T: AzBuf,
283{
284 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
285 T::azalea_read(buf).map(Box::new)
286 }
287 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
288 T::azalea_write(&**self, buf)
289 }
290}
291
292impl<A: AzBuf, B: AzBuf> AzBuf for (A, B) {
293 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
294 Ok((A::azalea_read(buf)?, B::azalea_read(buf)?))
295 }
296 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
297 self.0.azalea_write(buf)?;
298 self.1.azalea_write(buf)
299 }
300}
301
302impl<T: AzBuf> AzBuf for Arc<T> {
303 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
304 Ok(Arc::new(T::azalea_read(buf)?))
305 }
306 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
307 T::azalea_write(&**self, buf)
308 }
309}