steel_registry/data_components/
component_data.rs1use super::components::{Equippable, ItemEnchantments, Tool};
7use text_components::TextComponent;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum ComponentDataDiscriminant {
15 Empty,
16 Bool,
17 I32,
18 Float,
19 Tool,
20 Equippable,
21 Enchantments,
22 TextComponent,
23 Todo,
24 Other,
25}
26
27#[derive(Debug, Clone, PartialEq)]
53#[non_exhaustive]
54pub enum ComponentData {
55 Empty,
57
58 Bool(bool),
60 I32(i32),
63 Float(f32),
65
66 Tool(Tool),
68 Equippable(Equippable),
70 Enchantments(ItemEnchantments),
72 TextComponent(Box<TextComponent>),
74
75 Todo,
77
78 Other(Vec<u8>),
81}
82
83impl ComponentData {
84 #[must_use]
86 pub const fn is_empty(&self) -> bool {
87 matches!(self, Self::Empty)
88 }
89
90 #[must_use]
92 pub fn as_other(&self) -> Option<&[u8]> {
93 match self {
94 Self::Other(bytes) => Some(bytes),
95 _ => None,
96 }
97 }
98
99 #[must_use]
102 pub const fn discriminant(&self) -> ComponentDataDiscriminant {
103 match self {
104 Self::Empty => ComponentDataDiscriminant::Empty,
105 Self::Bool(_) => ComponentDataDiscriminant::Bool,
106 Self::I32(_) => ComponentDataDiscriminant::I32,
107 Self::Float(_) => ComponentDataDiscriminant::Float,
108 Self::Tool(_) => ComponentDataDiscriminant::Tool,
109 Self::Equippable(_) => ComponentDataDiscriminant::Equippable,
110 Self::Enchantments(_) => ComponentDataDiscriminant::Enchantments,
111 Self::TextComponent(_) => ComponentDataDiscriminant::TextComponent,
112 Self::Todo => ComponentDataDiscriminant::Todo,
113 Self::Other(_) => ComponentDataDiscriminant::Other,
114 }
115 }
116
117 #[must_use]
121 pub fn compute_hash(&self) -> i32 {
122 use steel_utils::hash::{ComponentHasher, HashComponent};
123
124 let mut hasher = ComponentHasher::new();
125
126 match self {
127 Self::Empty => hasher.put_empty(),
129 Self::Bool(v) => v.hash_component(&mut hasher),
130 Self::I32(v) => v.hash_component(&mut hasher),
131 Self::Float(v) => v.hash_component(&mut hasher),
132
133 Self::Tool(v) => v.hash_component(&mut hasher),
135 Self::Equippable(v) => v.hash_component(&mut hasher),
136 Self::Enchantments(v) => v.hash_component(&mut hasher),
137 Self::TextComponent(v) => v.hash_component(&mut hasher),
138
139 Self::Todo | Self::Other(_) => {
142 hasher.start_map();
143 hasher.end_map();
144 }
145 }
146
147 hasher.finish()
148 }
149}
150
151pub trait Component: Sized + Clone {
172 fn into_data(self) -> ComponentData;
174
175 fn from_data(data: ComponentData) -> Option<Self>;
178
179 fn from_data_ref(data: &ComponentData) -> Option<&Self>;
183}
184
185impl Component for () {
187 fn into_data(self) -> ComponentData {
188 ComponentData::Empty
189 }
190
191 fn from_data(data: ComponentData) -> Option<Self> {
192 match data {
193 ComponentData::Empty => Some(()),
194 _ => None,
195 }
196 }
197
198 fn from_data_ref(data: &ComponentData) -> Option<&Self> {
199 match data {
200 ComponentData::Empty => Some(&()),
201 _ => None,
202 }
203 }
204}
205
206impl Component for bool {
207 fn into_data(self) -> ComponentData {
208 ComponentData::Bool(self)
209 }
210
211 fn from_data(data: ComponentData) -> Option<Self> {
212 match data {
213 ComponentData::Bool(v) => Some(v),
214 _ => None,
215 }
216 }
217
218 fn from_data_ref(data: &ComponentData) -> Option<&Self> {
219 match data {
220 ComponentData::Bool(v) => Some(v),
221 _ => None,
222 }
223 }
224}
225
226impl Component for i32 {
227 fn into_data(self) -> ComponentData {
228 ComponentData::I32(self)
229 }
230
231 fn from_data(data: ComponentData) -> Option<Self> {
232 match data {
233 ComponentData::I32(v) => Some(v),
234 _ => None,
235 }
236 }
237
238 fn from_data_ref(data: &ComponentData) -> Option<&Self> {
239 match data {
240 ComponentData::I32(v) => Some(v),
241 _ => None,
242 }
243 }
244}
245
246impl Component for f32 {
247 fn into_data(self) -> ComponentData {
248 ComponentData::Float(self)
249 }
250
251 fn from_data(data: ComponentData) -> Option<Self> {
252 match data {
253 ComponentData::Float(v) => Some(v),
254 _ => None,
255 }
256 }
257
258 fn from_data_ref(data: &ComponentData) -> Option<&Self> {
259 match data {
260 ComponentData::Float(v) => Some(v),
261 _ => None,
262 }
263 }
264}
265
266impl Component for Tool {
267 fn into_data(self) -> ComponentData {
268 ComponentData::Tool(self)
269 }
270
271 fn from_data(data: ComponentData) -> Option<Self> {
272 match data {
273 ComponentData::Tool(v) => Some(v),
274 _ => None,
275 }
276 }
277
278 fn from_data_ref(data: &ComponentData) -> Option<&Self> {
279 match data {
280 ComponentData::Tool(v) => Some(v),
281 _ => None,
282 }
283 }
284}
285
286impl Component for ItemEnchantments {
287 fn into_data(self) -> ComponentData {
288 ComponentData::Enchantments(self)
289 }
290
291 fn from_data(data: ComponentData) -> Option<Self> {
292 match data {
293 ComponentData::Enchantments(v) => Some(v),
294 _ => None,
295 }
296 }
297
298 fn from_data_ref(data: &ComponentData) -> Option<&Self> {
299 match data {
300 ComponentData::Enchantments(v) => Some(v),
301 _ => None,
302 }
303 }
304}
305
306impl Component for Equippable {
307 fn into_data(self) -> ComponentData {
308 ComponentData::Equippable(self)
309 }
310
311 fn from_data(data: ComponentData) -> Option<Self> {
312 match data {
313 ComponentData::Equippable(v) => Some(v),
314 _ => None,
315 }
316 }
317
318 fn from_data_ref(data: &ComponentData) -> Option<&Self> {
319 match data {
320 ComponentData::Equippable(v) => Some(v),
321 _ => None,
322 }
323 }
324}
325
326impl Component for TextComponent {
327 fn into_data(self) -> ComponentData {
328 ComponentData::TextComponent(Box::new(self))
329 }
330
331 fn from_data(data: ComponentData) -> Option<Self> {
332 match data {
333 ComponentData::TextComponent(v) => Some(*v),
334 _ => None,
335 }
336 }
337
338 fn from_data_ref(data: &ComponentData) -> Option<&Self> {
339 match data {
340 ComponentData::TextComponent(v) => Some(v),
341 _ => None,
342 }
343 }
344}
345
346