luanti_protocol/types/
node_box.rs

1use anyhow::bail;
2use luanti_protocol_derive::{LuantiDeserialize, LuantiSerialize};
3
4use crate::wire::{
5    deser::{Deserialize, DeserializeError, DeserializeResult, Deserializer},
6    ser::{Serialize, SerializeResult, Serializer},
7};
8
9use super::{Array16, v3f};
10
11#[derive(Debug, Clone, PartialEq)]
12#[expect(
13    clippy::large_enum_variant,
14    reason = "// TODO consider `Box`ing variants"
15)]
16pub enum NodeBox {
17    Regular,
18    Fixed(NodeBoxFixed),
19    Wallmounted(NodeBoxWallmounted),
20    Leveled(NodeBoxLeveled),
21    Connected(NodeBoxConnected),
22}
23
24impl Serialize for NodeBox {
25    type Input = Self;
26    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
27        // Unused version number, always 6
28        u8::serialize(&6, ser)?;
29
30        let typ = match value {
31            NodeBox::Regular => 0,
32            NodeBox::Fixed(_) => 1,
33            NodeBox::Wallmounted(_) => 2,
34            NodeBox::Leveled(_) => 3,
35            NodeBox::Connected(_) => 4,
36        };
37        u8::serialize(&typ, ser)?;
38        match value {
39            NodeBox::Regular => Ok(()),
40            NodeBox::Fixed(value) => NodeBoxFixed::serialize(value, ser),
41            NodeBox::Wallmounted(value) => NodeBoxWallmounted::serialize(value, ser),
42            NodeBox::Leveled(value) => NodeBoxLeveled::serialize(value, ser),
43            NodeBox::Connected(value) => NodeBoxConnected::serialize(value, ser),
44        }
45    }
46}
47
48impl Deserialize for NodeBox {
49    type Output = Self;
50    fn deserialize(deser: &mut Deserializer<'_>) -> DeserializeResult<Self> {
51        let ver = u8::deserialize(deser)?;
52        if ver != 6 {
53            bail!(DeserializeError::InvalidValue("Invalid NodeBox ver".into(),));
54        }
55        let typ = u8::deserialize(deser)?;
56        match typ {
57            0 => Ok(NodeBox::Regular),
58            1 => Ok(NodeBox::Fixed(NodeBoxFixed::deserialize(deser)?)),
59            2 => Ok(NodeBox::Wallmounted(NodeBoxWallmounted::deserialize(
60                deser,
61            )?)),
62            3 => Ok(NodeBox::Leveled(NodeBoxLeveled::deserialize(deser)?)),
63            4 => Ok(NodeBox::Connected(NodeBoxConnected::deserialize(deser)?)),
64            _ => bail!(DeserializeError::InvalidValue(
65                "Invalid NodeBox type".into(),
66            )),
67        }
68    }
69}
70
71#[allow(non_camel_case_types, reason = "aligns with the original C++ codebase")]
72#[derive(Debug, Clone, PartialEq, LuantiSerialize, LuantiDeserialize)]
73pub struct aabb3f {
74    pub min_edge: v3f,
75    pub max_edge: v3f,
76}
77
78#[derive(Debug, Clone, PartialEq, LuantiSerialize, LuantiDeserialize)]
79pub struct NodeBoxLeveled {
80    #[wrap(Array16<aabb3f>)]
81    pub fixed: Vec<aabb3f>,
82}
83
84#[derive(Debug, Clone, PartialEq, LuantiSerialize, LuantiDeserialize)]
85pub struct NodeBoxFixed {
86    #[wrap(Array16<aabb3f>)]
87    pub fixed: Vec<aabb3f>,
88}
89
90#[derive(Debug, Clone, PartialEq, LuantiSerialize, LuantiDeserialize)]
91pub struct NodeBoxWallmounted {
92    pub wall_top: aabb3f,
93    pub wall_bottom: aabb3f,
94    pub wall_side: aabb3f,
95}
96
97#[derive(Debug, Clone, PartialEq, LuantiSerialize, LuantiDeserialize)]
98pub struct NodeBoxConnected {
99    #[wrap(Array16<aabb3f>)]
100    pub fixed: Vec<aabb3f>,
101    #[wrap(Array16<aabb3f>)]
102    pub connect_top: Vec<aabb3f>,
103    #[wrap(Array16<aabb3f>)]
104    pub connect_bottom: Vec<aabb3f>,
105    #[wrap(Array16<aabb3f>)]
106    pub connect_front: Vec<aabb3f>,
107    #[wrap(Array16<aabb3f>)]
108    pub connect_left: Vec<aabb3f>,
109    #[wrap(Array16<aabb3f>)]
110    pub connect_back: Vec<aabb3f>,
111    #[wrap(Array16<aabb3f>)]
112    pub connect_right: Vec<aabb3f>,
113    #[wrap(Array16<aabb3f>)]
114    pub disconnected_top: Vec<aabb3f>,
115    #[wrap(Array16<aabb3f>)]
116    pub disconnected_bottom: Vec<aabb3f>,
117    #[wrap(Array16<aabb3f>)]
118    pub disconnected_front: Vec<aabb3f>,
119    #[wrap(Array16<aabb3f>)]
120    pub disconnected_left: Vec<aabb3f>,
121    #[wrap(Array16<aabb3f>)]
122    pub disconnected_back: Vec<aabb3f>,
123    #[wrap(Array16<aabb3f>)]
124    pub disconnected_right: Vec<aabb3f>,
125    #[wrap(Array16<aabb3f>)]
126    pub disconnected: Vec<aabb3f>,
127    #[wrap(Array16<aabb3f>)]
128    pub disconnected_sides: Vec<aabb3f>,
129}