azalea_protocol/common/
tags.rs

1use std::{
2    io::{self, Cursor, Write},
3    ops::Deref,
4};
5
6use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
7use azalea_core::resource_location::ResourceLocation;
8use indexmap::IndexMap;
9
10#[derive(Clone, Debug, PartialEq)]
11pub struct TagMap(pub IndexMap<ResourceLocation, Vec<Tags>>);
12
13#[derive(Clone, Debug, PartialEq)]
14pub struct Tags {
15    pub name: ResourceLocation,
16    pub elements: Vec<i32>,
17}
18
19impl AzaleaRead for TagMap {
20    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
21        let length = u32::azalea_read_var(buf)? as usize;
22        let mut data = IndexMap::with_capacity(length);
23        for _ in 0..length {
24            let tag_type = ResourceLocation::azalea_read(buf)?;
25            let tags_count = i32::azalea_read_var(buf)? as usize;
26            let mut tags_vec = Vec::with_capacity(tags_count);
27            for _ in 0..tags_count {
28                let tags = Tags::azalea_read(buf)?;
29                tags_vec.push(tags);
30            }
31            data.insert(tag_type, tags_vec);
32        }
33        Ok(TagMap(data))
34    }
35}
36
37impl AzaleaWrite for TagMap {
38    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
39        (self.len() as u32).azalea_write_var(buf)?;
40        for (k, v) in &self.0 {
41            k.azalea_write(buf)?;
42            v.azalea_write(buf)?;
43        }
44        Ok(())
45    }
46}
47impl AzaleaRead for Tags {
48    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
49        let name = ResourceLocation::azalea_read(buf)?;
50        let elements = Vec::<i32>::azalea_read_var(buf)?;
51        Ok(Tags { name, elements })
52    }
53}
54
55impl AzaleaWrite for Tags {
56    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
57        self.name.azalea_write(buf)?;
58        self.elements.azalea_write_var(buf)?;
59        Ok(())
60    }
61}
62
63impl Deref for TagMap {
64    type Target = IndexMap<ResourceLocation, Vec<Tags>>;
65
66    fn deref(&self) -> &Self::Target {
67        &self.0
68    }
69}