chunkedge_binary/
id_set.rs

1use std::io::Write;
2
3use chunkedge_generated::registry_id::RegistryId;
4
5use crate::{Decode, Encode, VarInt};
6
7#[derive(Debug, PartialEq, Eq, Clone)]
8/// Represents a set of IDs in a certain registry, either directly (enumerated
9/// IDs) or indirectly (tag name).
10///
11/// # Variants
12///
13/// - `NamedSet(String)`: Represents a named set of IDs defined by a tag.
14/// - `AdHocSet(Vec<RegistryId>)`: Represents an ad-hoc set of IDs enumerated
15///   inline.
16pub enum IDSet {
17    NamedSet(String),
18    AdHocSet(Vec<RegistryId>),
19}
20
21impl Encode for IDSet {
22    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
23        match self {
24            IDSet::NamedSet(tag_name) => {
25                VarInt(0).encode(&mut w)?;
26                tag_name.encode(w)
27            }
28            IDSet::AdHocSet(ids) => {
29                VarInt((ids.len() + 1) as i32).encode(&mut w)?;
30                for id in ids {
31                    id.encode(&mut w)?;
32                }
33                Ok(())
34            }
35        }
36    }
37}
38
39impl<'a> Decode<'a> for IDSet {
40    fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
41        let type_id = VarInt::decode(r)?.0;
42        if type_id == 0 {
43            let tag_name = String::decode(r)?;
44            Ok(IDSet::NamedSet(tag_name))
45        } else {
46            let mut ids = Vec::with_capacity((type_id - 1) as usize);
47            for _ in 0..(type_id - 1) {
48                ids.push(RegistryId::new(VarInt::decode(r)?.0));
49            }
50            Ok(IDSet::AdHocSet(ids))
51        }
52    }
53}