valence_protocol/impls/
primitive.rs

1use std::io::Write;
2use std::slice;
3
4use anyhow::ensure;
5use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
6
7use crate::{Decode, Encode};
8
9impl Encode for bool {
10    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
11        Ok(w.write_u8(u8::from(*self))?)
12    }
13
14    fn encode_slice(slice: &[bool], mut w: impl Write) -> anyhow::Result<()> {
15        // SAFETY: Bools have the same layout as u8.
16        let bytes = unsafe { slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len()) };
17        // Bools are guaranteed to have the correct bit pattern.
18        Ok(w.write_all(bytes)?)
19    }
20}
21
22impl Decode<'_> for bool {
23    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
24        let n = r.read_u8()?;
25        ensure!(n <= 1, "decoded boolean byte is not 0 or 1 (got {n})");
26        Ok(n == 1)
27    }
28}
29
30impl Encode for u8 {
31    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
32        Ok(w.write_u8(*self)?)
33    }
34
35    fn encode_slice(slice: &[u8], mut w: impl Write) -> anyhow::Result<()> {
36        Ok(w.write_all(slice)?)
37    }
38}
39
40impl Decode<'_> for u8 {
41    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
42        Ok(r.read_u8()?)
43    }
44}
45
46impl Encode for i8 {
47    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
48        Ok(w.write_i8(*self)?)
49    }
50
51    fn encode_slice(slice: &[i8], mut w: impl Write) -> anyhow::Result<()> {
52        // SAFETY: i8 has the same layout as u8.
53        let bytes = unsafe { slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len()) };
54        Ok(w.write_all(bytes)?)
55    }
56}
57
58impl Decode<'_> for i8 {
59    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
60        Ok(r.read_i8()?)
61    }
62}
63
64impl Encode for u16 {
65    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
66        Ok(w.write_u16::<BigEndian>(*self)?)
67    }
68}
69
70impl Decode<'_> for u16 {
71    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
72        Ok(r.read_u16::<BigEndian>()?)
73    }
74}
75
76impl Encode for i16 {
77    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
78        Ok(w.write_i16::<BigEndian>(*self)?)
79    }
80}
81
82impl Decode<'_> for i16 {
83    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
84        Ok(r.read_i16::<BigEndian>()?)
85    }
86}
87
88impl Encode for u32 {
89    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
90        Ok(w.write_u32::<BigEndian>(*self)?)
91    }
92}
93
94impl Decode<'_> for u32 {
95    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
96        Ok(r.read_u32::<BigEndian>()?)
97    }
98}
99
100impl Encode for i32 {
101    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
102        Ok(w.write_i32::<BigEndian>(*self)?)
103    }
104}
105
106impl Decode<'_> for i32 {
107    fn decode(r: &mut &'_ [u8]) -> anyhow::Result<Self> {
108        Ok(r.read_i32::<BigEndian>()?)
109    }
110}
111
112impl Encode for u64 {
113    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
114        Ok(w.write_u64::<BigEndian>(*self)?)
115    }
116}
117
118impl Decode<'_> for u64 {
119    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
120        Ok(r.read_u64::<BigEndian>()?)
121    }
122}
123
124impl Encode for i64 {
125    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
126        Ok(w.write_i64::<BigEndian>(*self)?)
127    }
128}
129
130impl Decode<'_> for i64 {
131    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
132        Ok(r.read_i64::<BigEndian>()?)
133    }
134}
135
136impl Encode for u128 {
137    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
138        Ok(w.write_u128::<BigEndian>(*self)?)
139    }
140}
141
142impl Decode<'_> for u128 {
143    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
144        Ok(r.read_u128::<BigEndian>()?)
145    }
146}
147
148impl Encode for i128 {
149    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
150        Ok(w.write_i128::<BigEndian>(*self)?)
151    }
152}
153
154impl Decode<'_> for i128 {
155    fn decode(r: &mut &'_ [u8]) -> anyhow::Result<Self> {
156        Ok(r.read_i128::<BigEndian>()?)
157    }
158}
159
160impl Encode for f32 {
161    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
162        ensure!(
163            self.is_finite(),
164            "attempt to encode non-finite f32 ({})",
165            self
166        );
167        Ok(w.write_f32::<BigEndian>(*self)?)
168    }
169}
170
171impl Decode<'_> for f32 {
172    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
173        let f = r.read_f32::<BigEndian>()?;
174        ensure!(f.is_finite(), "attempt to decode non-finite f32 ({f})");
175        Ok(f)
176    }
177}
178
179impl Encode for f64 {
180    fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
181        ensure!(
182            self.is_finite(),
183            "attempt to encode non-finite f64 ({})",
184            self
185        );
186        Ok(w.write_f64::<BigEndian>(*self)?)
187    }
188}
189
190impl Decode<'_> for f64 {
191    fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
192        let f = r.read_f64::<BigEndian>()?;
193        ensure!(f.is_finite(), "attempt to decode non-finite f64 ({f})");
194        Ok(f)
195    }
196}