oc_wasm_helpers/
inventory.rs1use crate::map_decoder;
2use minicbor::decode::{Decode, Decoder, Error};
3
4#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
9pub struct ItemStack<'buffer> {
10 pub name: &'buffer str,
14
15 pub label: &'buffer str,
19
20 pub size: u32,
22
23 pub max_size: u32,
25
26 pub damage: u32,
28
29 pub max_damage: u32,
31
32 pub has_tag: bool,
34}
35
36impl<'buffer, Context> Decode<'buffer, Context> for ItemStack<'buffer> {
37 fn decode(d: &mut Decoder<'buffer>, context: &mut Context) -> Result<Self, Error> {
38 match OptionItemStack::decode(d, context)?.into() {
39 Some(s) => Ok(s),
40 None => Err(Error::message("missing item stack")),
41 }
42 }
43}
44
45#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
54#[repr(transparent)]
55pub struct OptionItemStack<'buffer>(pub Option<ItemStack<'buffer>>);
56
57impl<'buffer, Context> Decode<'buffer, Context> for OptionItemStack<'buffer> {
58 fn decode(d: &mut Decoder<'buffer>, context: &mut Context) -> Result<Self, Error> {
59 map_decoder::decode_nullable::<OptionItemStackBuilder<'buffer>, Context>(d, context)
60 }
61}
62
63impl<'buffer> From<OptionItemStack<'buffer>> for Option<ItemStack<'buffer>> {
64 fn from(x: OptionItemStack<'buffer>) -> Option<ItemStack<'buffer>> {
65 x.0
66 }
67}
68
69#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
71pub struct OptionItemStackBuilder<'buffer> {
72 name: Option<&'buffer str>,
76
77 label: Option<&'buffer str>,
81
82 size: Option<u32>,
84
85 max_size: Option<u32>,
87
88 damage: Option<u32>,
90
91 max_damage: Option<u32>,
93
94 has_tag: Option<bool>,
96}
97
98impl<'buffer> map_decoder::Builder<'buffer> for OptionItemStackBuilder<'buffer> {
99 type Output = OptionItemStack<'buffer>;
100
101 fn entry<Context>(
102 &mut self,
103 key: &str,
104 d: &mut Decoder<'buffer>,
105 _: &mut Context,
106 ) -> Result<bool, Error> {
107 match key {
108 "name" => {
109 self.name = Some(d.str()?);
110 Ok(true)
111 }
112 "label" => {
113 self.label = Some(d.str()?);
114 Ok(true)
115 }
116 "size" => {
117 self.size = Some(d.u32()?);
118 Ok(true)
119 }
120 "maxSize" => {
121 self.max_size = Some(d.u32()?);
122 Ok(true)
123 }
124 "damage" => {
125 self.damage = Some(d.u32()?);
126 Ok(true)
127 }
128 "maxDamage" => {
129 self.max_damage = Some(d.u32()?);
130 Ok(true)
131 }
132 "hasTag" => {
133 self.has_tag = Some(d.bool()?);
134 Ok(true)
135 }
136 _ => Ok(false),
137 }
138 }
139
140 fn build(self) -> Result<Self::Output, Error> {
141 if let Some(name) = self.name {
143 if let Some(label) = self.label {
144 if let Some(size) = self.size {
145 if let Some(max_size) = self.max_size {
146 if let Some(damage) = self.damage {
147 if let Some(max_damage) = self.max_damage {
148 if let Some(has_tag) = self.has_tag {
149 return Ok(OptionItemStack(
152 if name == "minecraft:air" && size == 0 {
153 None
154 } else {
155 Some(ItemStack {
156 name,
157 label,
158 size,
159 max_size,
160 damage,
161 max_damage,
162 has_tag,
163 })
164 },
165 ));
166 }
167 }
168 }
169 }
170 }
171 }
172 }
173
174 if (
176 self.name,
177 self.label,
178 self.size,
179 self.max_size,
180 self.damage,
181 self.max_damage,
182 self.has_tag,
183 ) == (None, None, None, None, None, None, None)
184 {
185 return Ok(OptionItemStack(None));
186 }
187
188 Err(Error::message("missing key in item stack"))
190 }
191}
192
193impl<'buffer> map_decoder::NullableBuilder<'buffer> for OptionItemStackBuilder<'buffer> {
194 fn build_null() -> OptionItemStack<'buffer> {
195 OptionItemStack(None)
196 }
197}