chunkedge_binary/
id_or.rs

1use std::fmt::Debug;
2use std::io::Write;
3
4use anyhow::Error;
5use chunkedge_generated::registry_id::RegistryId;
6
7use crate::{Decode, Encode, VarInt};
8
9#[derive(Clone, Debug, PartialEq)]
10pub enum IdOr<T: Encode + Clone + Debug + PartialEq> {
11    Id(RegistryId),
12    Inline(T),
13}
14
15impl<T: Encode + Clone + Debug + PartialEq> IdOr<T> {
16    pub fn id<I: Into<RegistryId>>(id: I) -> Self {
17        Self::Id(id.into())
18    }
19
20    pub fn inline(value: T) -> Self {
21        Self::Inline(value)
22    }
23}
24
25impl<T: Encode + Clone + Debug + PartialEq> Encode for IdOr<T> {
26    fn encode(&self, mut buf: impl Write) -> anyhow::Result<()> {
27        match self {
28            Self::Id(id) => VarInt(id.id() + 1).encode(buf),
29            Self::Inline(value) => {
30                VarInt(0).encode(&mut buf)?;
31                value.encode(&mut buf)
32            }
33        }
34    }
35}
36
37impl<'a, T: Decode<'a> + Encode + Clone + Debug + PartialEq> Decode<'a> for IdOr<T> {
38    fn decode(buf: &mut &'a [u8]) -> Result<Self, Error> {
39        let id = VarInt::decode(buf)?;
40        if id == VarInt(0) {
41            let value = T::decode(buf)?;
42            Ok(Self::Inline(value))
43        } else {
44            let registry_id = RegistryId::new(id.0 - 1);
45            Ok(Self::Id(registry_id))
46        }
47    }
48}