1use core::panic;
7
8use crate::data::{DeserializeCopy, Deserializeable, Serializeable};
9
10pub mod array {
11 use std::{
14 mem::ManuallyDrop,
15 ops::{Deref, DerefMut, Index, IndexMut},
16 ptr,
17 slice::{self, SliceIndex},
18 };
19 #[derive(Clone, Debug)]
22 pub struct NbtArray<T> {
23 inner: Box<[T]>,
24 }
25
26 impl<T> Default for NbtArray<T> {
27 fn default() -> Self {
28 Self {
29 inner: Box::new(<[T; 0]>::default()),
30 }
31 }
32 }
33
34 impl<T> Deref for NbtArray<T> {
35 type Target = [T];
36
37 #[inline]
38 fn deref(&self) -> &Self::Target {
39 self.inner.deref()
40 }
41 }
42
43 impl<T> DerefMut for NbtArray<T> {
44 #[inline]
45 fn deref_mut(&mut self) -> &mut Self::Target {
46 self.inner.deref_mut()
47 }
48 }
49
50 impl<T> From<Vec<T>> for NbtArray<T> {
51 #[inline]
52 fn from(v: Vec<T>) -> Self {
53 Self {
54 inner: v.into_boxed_slice(),
55 }
56 }
57 }
58
59 impl<T> From<Box<[T]>> for NbtArray<T> {
60 #[inline]
61 fn from(v: Box<[T]>) -> Self {
62 Self { inner: v }
63 }
64 }
65
66 impl<T, const N: usize> From<[T; N]> for NbtArray<T> {
67 #[inline]
68 fn from(v: [T; N]) -> Self {
69 Self { inner: Box::new(v) }
70 }
71 }
72
73 impl<T, I: SliceIndex<[T]>> Index<I> for NbtArray<T> {
74 type Output = I::Output;
75
76 #[inline]
77 fn index(&self, index: I) -> &Self::Output {
78 self.inner.index(index)
79 }
80 }
81
82 impl<T, I: SliceIndex<[T]>> IndexMut<I> for NbtArray<T> {
83 #[inline]
84 fn index_mut(&mut self, index: I) -> &mut Self::Output {
85 self.inner.index_mut(index)
86 }
87 }
88
89 pub struct IntoIter<T> {
92 inner: Box<[ManuallyDrop<T>]>,
93 position: usize,
94 }
95
96 impl<T> Drop for IntoIter<T> {
97 fn drop(&mut self) {
98 for i in self.position..self.inner.len() {
99 unsafe { ManuallyDrop::drop(&mut self.inner[i]) }
102 }
103 }
104 }
105
106 impl<T> Iterator for IntoIter<T> {
107 type Item = T;
108
109 fn next(&mut self) -> Option<Self::Item> {
110 self.position = self.position.checked_add(1).unwrap();
111 self.inner
114 .get_mut(self.position - 1)
115 .map(|m| unsafe { ManuallyDrop::take(m) })
116 }
117 }
118
119 impl<T> IntoIterator for NbtArray<T> {
120 type Item = T;
121
122 type IntoIter = IntoIter<T>;
123
124 fn into_iter(self) -> Self::IntoIter {
125 let len = self.inner.len();
126 let ptr = Box::into_raw(self.inner).cast::<T>();
127 let inner = unsafe {
129 Box::from_raw(ptr::slice_from_raw_parts_mut(
130 ptr.cast::<ManuallyDrop<T>>(),
131 len,
132 ))
133 };
134 IntoIter { inner, position: 0 }
135 }
136 }
137
138 pub struct Iter<'a, T: 'a>(slice::Iter<'a, T>);
141
142 impl<'a, T: 'a> Iterator for Iter<'a, T> {
143 type Item = &'a T;
144 fn next(&mut self) -> Option<&'a T> {
145 self.0.next()
146 }
147 }
148
149 pub struct IterMut<'a, T: 'a>(slice::IterMut<'a, T>);
152
153 impl<'a, T: 'a> Iterator for IterMut<'a, T> {
154 type Item = &'a mut T;
155 fn next(&mut self) -> Option<&'a mut T> {
156 self.0.next()
157 }
158 }
159
160 impl<T> NbtArray<T> {
161 pub fn iter(&self) -> Iter<T> {
164 Iter(self.inner.iter())
165 }
166 pub fn iter_mut(&mut self) -> IterMut<T> {
169 IterMut(self.inner.iter_mut())
170 }
171 }
172
173 impl<'a, T> IntoIterator for &'a NbtArray<T> {
174 type Item = &'a T;
175
176 type IntoIter = Iter<'a, T>;
177
178 fn into_iter(self) -> Self::IntoIter {
179 self.iter()
180 }
181 }
182
183 impl<'a, T> IntoIterator for &'a mut NbtArray<T> {
184 type Item = &'a mut T;
185
186 type IntoIter = IterMut<'a, T>;
187
188 fn into_iter(self) -> Self::IntoIter {
189 self.iter_mut()
190 }
191 }
192}
193
194fake_enum! {
195 #[repr(u8)]
196 #[derive(Default,Hash)]
197 pub enum struct TagType{
198 End = 0,
202 Byte = 1,
204 Short = 2,
206 Int = 3,
208 Long = 4,
210 Float = 5,
212 Double = 6,
214 ByteArray = 7,
216 String = 8,
218 List = 9,
220 Compound = 10,
222 IntArray = 11,
224 LongArray = 12,
226 FloatArray = 13,
228 DoubleArray = 14,
230 Uuid = 15
232 }
233}
234
235impl Serializeable for TagType {
236 fn serialize<W: crate::data::DataOutput + ?Sized>(
237 &self,
238 output: &mut W,
239 ) -> std::io::Result<()> {
240 self.0.serialize(output)
241 }
242}
243
244impl Deserializeable for TagType {
245 fn deserialize<R: crate::data::DataInput + ?Sized>(
246 &mut self,
247 input: &mut R,
248 ) -> std::io::Result<()> {
249 self.0.deserialize(input)
250 }
251}
252
253impl DeserializeCopy for TagType {
254 fn deserialize_copy<R: crate::data::DataInput + ?Sized>(
255 input: &mut R,
256 ) -> std::io::Result<Self> {
257 Ok(Self(DeserializeCopy::deserialize_copy(input)?))
258 }
259}
260
261pub mod list {
264 use std::{fmt::Display, io::ErrorKind};
265
266 use crate::data::{DeserializeCopy, Deserializeable, OutOfRange, Serializeable};
267
268 use super::{NbtTag, TagType};
269
270 #[derive(Clone, Default, Debug)]
274 pub struct NbtList {
275 tag: TagType,
276 elements: Vec<NbtTag>,
277 }
278
279 #[derive(Debug, Clone)]
282 pub struct WrongTagType {
283 tag: NbtTag,
284 expected: TagType,
285 }
286
287 impl Display for WrongTagType {
288 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
289 f.write_fmt(format_args!(
290 "Invalid tag with type {:?} (list elements have type {:?})",
291 &self.tag, &self.expected
292 ))
293 }
294 }
295
296 impl WrongTagType {
297 pub fn into_tag(self) -> NbtTag {
300 self.tag
301 }
302
303 pub fn expected_tag(&self) -> TagType {
306 self.expected
307 }
308 }
309
310 impl std::error::Error for WrongTagType {}
311
312 impl NbtList {
313 pub const fn new() -> Self {
316 Self {
317 tag: TagType::End,
318 elements: Vec::new(),
319 }
320 }
321
322 pub fn insert(&mut self, tag: NbtTag) -> Result<(), WrongTagType> {
325 if self.elements.is_empty() {
326 self.tag = tag.tag_type();
327 self.elements.push(tag);
328 Ok(())
329 } else if self.tag == tag.tag_type() {
330 self.elements.push(tag);
331 Ok(())
332 } else {
333 Err(WrongTagType {
334 tag,
335 expected: self.tag,
336 })
337 }
338 }
339 }
340
341 impl Serializeable for NbtList {
342 fn serialize<W: crate::data::DataOutput + ?Sized>(
343 &self,
344 output: &mut W,
345 ) -> std::io::Result<()> {
346 self.tag.serialize(output)?;
347 let len = self.elements.len();
348 if len > (i32::MAX as usize) {
349 return Err(std::io::Error::new(ErrorKind::InvalidData, OutOfRange(len)));
350 }
351 (len as i32).serialize(output)?;
352 for t in &self.elements {
353 t.serialize(output)?;
354 }
355 Ok(())
356 }
357 }
358 impl Deserializeable for NbtList {
359 fn deserialize<R: crate::data::DataInput + ?Sized>(
360 &mut self,
361 input: &mut R,
362 ) -> std::io::Result<()> {
363 let tt = TagType::deserialize_copy(input)?;
364 let len = i32::deserialize_copy(input)?;
365 if len < 0 {
366 return Err(std::io::Error::new(ErrorKind::InvalidData, OutOfRange(len)));
367 }
368 let mut items = Vec::with_capacity(len as usize);
369 items.resize_with(len as usize, || NbtTag::default_for_tag(tt));
370 for i in &mut items {
371 i.deserialize(input)?;
372 }
373 self.tag = tt;
374 self.elements = items;
375 Ok(())
376 }
377 }
378 impl DeserializeCopy for NbtList {
379 fn deserialize_copy<R: crate::data::DataInput + ?Sized>(
380 input: &mut R,
381 ) -> std::io::Result<Self> {
382 let tt = TagType::deserialize_copy(input)?;
383 let len = i32::deserialize_copy(input)?;
384 if len < 0 {
385 return Err(std::io::Error::new(ErrorKind::InvalidData, OutOfRange(len)));
386 }
387 let mut items = Vec::with_capacity(len as usize);
388 items.resize_with(len as usize, || NbtTag::default_for_tag(tt));
389 for i in &mut items {
390 i.deserialize(input)?;
391 }
392 Ok(Self {
393 tag: tt,
394 elements: items,
395 })
396 }
397 }
398}
399
400pub mod compound {
403 use std::{collections::HashMap, io::ErrorKind, ops::Index};
404
405 use crate::data::{DeserializeCopy, Deserializeable, Serializeable};
406
407 use super::{NbtTag, TagType};
408
409 #[derive(Clone, Debug, Default)]
412 pub struct NbtCompound {
413 inner: HashMap<String, NbtTag>,
414 }
415
416 impl NbtCompound {
417 pub fn new() -> NbtCompound {
420 Self {
421 inner: HashMap::new(),
422 }
423 }
424
425 pub fn get<S: AsRef<str> + ?Sized>(&self, st: &S) -> Option<&NbtTag> {
428 self.inner.get(st.as_ref())
429 }
430
431 pub fn get_mut<S: AsRef<str> + ?Sized>(&mut self, st: &S) -> Option<&mut NbtTag> {
434 self.inner.get_mut(st.as_ref())
435 }
436
437 pub fn insert(&mut self, name: String, value: NbtTag) -> Option<NbtTag> {
440 self.inner.insert(name, value)
441 }
442 }
443
444 impl<S: AsRef<str>> Index<S> for NbtCompound {
445 type Output = NbtTag;
446
447 fn index(&self, index: S) -> &Self::Output {
448 &self.inner[index.as_ref()]
449 }
450 }
451
452 impl Serializeable for NbtCompound {
453 fn serialize<W: crate::data::DataOutput + ?Sized>(
454 &self,
455 output: &mut W,
456 ) -> std::io::Result<()> {
457 for (k, v) in &self.inner {
458 let ty = v.tag_type();
459 if TagType::End == ty {
460 return Err(std::io::Error::new(
461 ErrorKind::InvalidData,
462 "Embedded Tag Ends cannot be serialized",
463 ));
464 }
465 ty.serialize(output)?;
466 k.serialize(output)?;
467 v.serialize(output)?;
468 }
469 TagType::End.serialize(output)
470 }
471 }
472
473 impl Deserializeable for NbtCompound {
474 fn deserialize<R: crate::data::DataInput + ?Sized>(
475 &mut self,
476 input: &mut R,
477 ) -> std::io::Result<()> {
478 self.inner.clear();
479 loop {
480 let ty = TagType::deserialize_copy(input)?;
481 if ty == TagType::End {
482 return Ok(());
483 }
484 let name = String::deserialize_copy(input)?;
485 let mut tag = NbtTag::default_for_tag(ty);
486 tag.deserialize(input)?;
487 self.inner.insert(name, tag);
488 }
489 }
490 }
491
492 impl DeserializeCopy for NbtCompound {
493 fn deserialize_copy<R: crate::data::DataInput + ?Sized>(
494 input: &mut R,
495 ) -> std::io::Result<Self> {
496 let mut inner = HashMap::new();
497 loop {
498 let ty = TagType::deserialize_copy(input)?;
499 if ty == TagType::End {
500 return Ok(Self { inner });
501 }
502 let name = String::deserialize_copy(input)?;
503 let mut tag = NbtTag::default_for_tag(ty);
504 tag.deserialize(input)?;
505 inner.insert(name, tag);
506 }
507 }
508 }
509}
510
511#[derive(Clone, Debug)]
514pub enum NbtTag {
515 End,
519 Byte(u8),
522 Short(i16),
525 Int(i32),
528 Long(i64),
531 Float(f32),
534 Double(f64),
537 ByteArray(array::NbtArray<u8>),
540 String(String),
543 List(list::NbtList),
546 Compound(compound::NbtCompound),
549 IntArray(array::NbtArray<i32>),
552 LongArray(array::NbtArray<i64>),
555 FloatArray(array::NbtArray<f32>),
558 DoubleArray(array::NbtArray<f64>),
561 Uuid(crate::uuid::UUID),
564}
565
566impl NbtTag {
567 pub fn tag_type(&self) -> TagType {
570 match self {
571 Self::End => TagType::End,
572 Self::Byte(_) => TagType::Byte,
573 NbtTag::Short(_) => TagType::Short,
574 NbtTag::Int(_) => TagType::Int,
575 NbtTag::Long(_) => TagType::Long,
576 NbtTag::Float(_) => TagType::Float,
577 NbtTag::Double(_) => TagType::Double,
578 NbtTag::ByteArray(_) => TagType::ByteArray,
579 NbtTag::String(_) => TagType::String,
580 NbtTag::List(_) => TagType::List,
581 NbtTag::Compound(_) => TagType::Compound,
582 NbtTag::IntArray(_) => TagType::IntArray,
583 NbtTag::LongArray(_) => TagType::LongArray,
584 NbtTag::FloatArray(_) => TagType::FloatArray,
585 NbtTag::DoubleArray(_) => TagType::DoubleArray,
586 NbtTag::Uuid(_) => TagType::Uuid,
587 }
588 }
589
590 pub fn default_for_tag(ty: TagType) -> Self {
595 match ty {
596 TagType::End => Self::End,
597 TagType::Byte => Self::Byte(0),
598 TagType::Short => Self::Short(0),
599 TagType::Int => Self::Int(0),
600 TagType::Float => Self::Float(0.0),
601 TagType::Double => Self::Double(0.0),
602 TagType::ByteArray => Self::ByteArray(Default::default()),
603 TagType::String => Self::String(Default::default()),
604 TagType::List => Self::List(Default::default()),
605 TagType::Compound => Self::Compound(Default::default()),
606 TagType::IntArray => Self::IntArray(Default::default()),
607 TagType::LongArray => Self::LongArray(Default::default()),
608 TagType::FloatArray => Self::FloatArray(Default::default()),
609 TagType::DoubleArray => Self::DoubleArray(Default::default()),
610 TagType::Uuid => Self::Uuid(Default::default()),
611 _ => panic!("Invalid tag type"),
612 }
613 }
614}
615
616impl Serializeable for NbtTag {
617 fn serialize<W: crate::data::DataOutput + ?Sized>(
618 &self,
619 output: &mut W,
620 ) -> std::io::Result<()> {
621 match self {
622 NbtTag::End => Ok(()),
623 NbtTag::Byte(v) => v.serialize(output),
624 NbtTag::Short(v) => v.serialize(output),
625 NbtTag::Int(v) => v.serialize(output),
626 NbtTag::Long(v) => v.serialize(output),
627 NbtTag::Float(v) => v.serialize(output),
628 NbtTag::Double(v) => v.serialize(output),
629 NbtTag::ByteArray(v) => v.serialize(output),
630 NbtTag::String(v) => v.serialize(output),
631 NbtTag::List(v) => v.serialize(output),
632 NbtTag::Compound(v) => v.serialize(output),
633 NbtTag::IntArray(v) => v.serialize(output),
634 NbtTag::LongArray(v) => v.serialize(output),
635 NbtTag::FloatArray(v) => v.serialize(output),
636 NbtTag::DoubleArray(v) => v.serialize(output),
637 NbtTag::Uuid(v) => v.serialize(output),
638 }
639 }
640}
641
642impl Deserializeable for NbtTag {
643 fn deserialize<W: crate::data::DataInput + ?Sized>(
644 &mut self,
645 output: &mut W,
646 ) -> std::io::Result<()> {
647 match self {
648 NbtTag::End => Ok(()),
649 NbtTag::Byte(v) => v.deserialize(output),
650 NbtTag::Short(v) => v.deserialize(output),
651 NbtTag::Int(v) => v.deserialize(output),
652 NbtTag::Long(v) => v.deserialize(output),
653 NbtTag::Float(v) => v.deserialize(output),
654 NbtTag::Double(v) => v.deserialize(output),
655 NbtTag::ByteArray(v) => v.deserialize(output),
656 NbtTag::String(v) => v.deserialize(output),
657 NbtTag::List(v) => v.deserialize(output),
658 NbtTag::Compound(v) => v.deserialize(output),
659 NbtTag::IntArray(v) => v.deserialize(output),
660 NbtTag::LongArray(v) => v.deserialize(output),
661 NbtTag::FloatArray(v) => v.deserialize(output),
662 NbtTag::DoubleArray(v) => v.deserialize(output),
663 NbtTag::Uuid(v) => v.deserialize(output),
664 }
665 }
666}