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