steel_utils/serial/
write.rs1#![expect(
2 clippy::disallowed_types,
3 reason = "HashMap is used directly to implement WriteTo; project types are not available here"
4)]
5use std::{
6 collections::HashMap,
7 hash::BuildHasher,
8 io::{Result, Write},
9};
10
11use simdnbt::{
12 ToNbtTag,
13 owned::{NbtCompound, NbtTag},
14};
15use text_components::TextComponent;
16use uuid::Uuid;
17
18use crate::{
19 BlockPos, Identifier, PackedBlockPos,
20 codec::VarInt,
21 serial::{PrefixedWrite, WriteTo},
22};
23
24impl WriteTo for bool {
25 fn write(&self, writer: &mut impl Write) -> Result<()> {
26 u8::from(*self).write(writer)?;
27 Ok(())
28 }
29}
30
31impl WriteTo for u8 {
32 fn write(&self, writer: &mut impl Write) -> Result<()> {
33 writer.write_all(&self.to_be_bytes())
34 }
35}
36
37impl WriteTo for u16 {
38 fn write(&self, writer: &mut impl Write) -> Result<()> {
39 writer.write_all(&self.to_be_bytes())
40 }
41}
42
43impl WriteTo for u32 {
44 fn write(&self, writer: &mut impl Write) -> Result<()> {
45 writer.write_all(&self.to_be_bytes())
46 }
47}
48
49impl WriteTo for u64 {
50 fn write(&self, writer: &mut impl Write) -> Result<()> {
51 writer.write_all(&self.to_be_bytes())
52 }
53}
54
55impl WriteTo for i8 {
56 fn write(&self, writer: &mut impl Write) -> Result<()> {
57 writer.write_all(&self.to_be_bytes())
58 }
59}
60
61impl WriteTo for i16 {
62 fn write(&self, writer: &mut impl Write) -> Result<()> {
63 writer.write_all(&self.to_be_bytes())
64 }
65}
66
67impl WriteTo for i32 {
68 fn write(&self, writer: &mut impl Write) -> Result<()> {
69 writer.write_all(&self.to_be_bytes())
70 }
71}
72
73impl WriteTo for i64 {
74 fn write(&self, writer: &mut impl Write) -> Result<()> {
75 writer.write_all(&self.to_be_bytes())
76 }
77}
78
79impl WriteTo for f32 {
80 fn write(&self, writer: &mut impl Write) -> Result<()> {
81 writer.write_all(&self.to_be_bytes())
82 }
83}
84
85impl WriteTo for f64 {
86 fn write(&self, writer: &mut impl Write) -> Result<()> {
87 writer.write_all(&self.to_be_bytes())
88 }
89}
90
91impl<T: WriteTo> WriteTo for Option<T> {
92 fn write(&self, writer: &mut impl Write) -> Result<()> {
93 if let Some(value) = self {
94 true.write(writer)?;
95 value.write(writer)
96 } else {
97 false.write(writer)
98 }
99 }
100}
101
102impl<T: WriteTo, const N: usize> WriteTo for [T; N] {
103 fn write(&self, writer: &mut impl Write) -> Result<()> {
104 for i in self {
105 i.write(writer)?;
106 }
107 Ok(())
108 }
109}
110
111impl<T: WriteTo, Z: WriteTo> WriteTo for (T, Z) {
112 fn write(&self, writer: &mut impl Write) -> Result<()> {
113 self.0.write(writer)?;
114 self.1.write(writer)
115 }
116}
117
118impl<K: WriteTo, V: WriteTo, S: BuildHasher> WriteTo for HashMap<K, V, S> {
119 fn write(&self, writer: &mut impl Write) -> Result<()> {
120 VarInt(self.len() as i32).write(writer)?;
121 for (key, value) in self {
122 key.write(writer)?;
123 value.write(writer)?;
124 }
125 Ok(())
126 }
127}
128
129impl<T: WriteTo> WriteTo for Vec<T> {
130 fn write(&self, writer: &mut impl Write) -> Result<()> {
131 self.write_prefixed::<VarInt>(writer)
132 }
133}
134
135impl WriteTo for BlockPos {
136 fn write(&self, writer: &mut impl Write) -> Result<()> {
137 PackedBlockPos::from(*self).write(writer)
138 }
139}
140
141impl WriteTo for TextComponent {
142 fn write(&self, writer: &mut impl Write) -> Result<()> {
143 WriteTo::write(&self.to_nbt_tag(), writer)?;
144 Ok(())
145 }
146}
147
148impl WriteTo for Uuid {
149 fn write(&self, writer: &mut impl Write) -> Result<()> {
150 let (most_significant_bits, least_significant_bits) = self.as_u64_pair();
151 most_significant_bits.write(writer)?;
152 least_significant_bits.write(writer)?;
153 Ok(())
154 }
155}
156
157impl WriteTo for Identifier {
158 fn write(&self, writer: &mut impl Write) -> Result<()> {
159 self.to_string().write_prefixed::<VarInt>(writer)?;
160 Ok(())
161 }
162}
163
164impl WriteTo for NbtTag {
165 fn write(&self, writer: &mut impl Write) -> Result<()> {
166 let mut buf = Vec::new();
167 self.write(&mut buf);
168 writer.write_all(&buf)?;
169 Ok(())
170 }
171}
172
173impl WriteTo for NbtCompound {
174 fn write(&self, writer: &mut impl Write) -> Result<()> {
175 let mut buf = Vec::new();
176 self.write(&mut buf);
177 writer.write_all(&buf)?;
178 Ok(())
179 }
180}
181
182#[derive(Debug, Clone)]
189pub struct OptionalNbt(pub Option<NbtCompound>);
190
191impl WriteTo for OptionalNbt {
192 fn write(&self, writer: &mut impl Write) -> Result<()> {
193 match &self.0 {
194 Some(compound) => {
195 writer.write_all(&[0x0A])?;
198 let mut buf = Vec::new();
199 compound.write(&mut buf);
200 writer.write_all(&buf)?;
201 }
202 None => {
203 writer.write_all(&[0x00])?;
205 }
206 }
207 Ok(())
208 }
209}
210
211impl From<Option<NbtCompound>> for OptionalNbt {
212 fn from(opt: Option<NbtCompound>) -> Self {
213 Self(opt)
214 }
215}