valence_protocol/impls/
other.rs
1use std::io::Write;
2
3use anyhow::Context;
4use uuid::Uuid;
5use valence_generated::block::{BlockEntityKind, BlockKind, BlockState};
6use valence_generated::item::ItemKind;
7use valence_ident::{Ident, IdentError};
8use valence_nbt::Compound;
9
10use crate::{Decode, Encode, VarInt};
11
12impl<T: Encode> Encode for Option<T> {
13 fn encode(&self, mut w: impl Write) -> anyhow::Result<()> {
14 match self {
15 Some(t) => {
16 true.encode(&mut w)?;
17 t.encode(w)
18 }
19 None => false.encode(w),
20 }
21 }
22}
23
24impl<'a, T: Decode<'a>> Decode<'a> for Option<T> {
25 fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
26 Ok(if bool::decode(r)? {
27 Some(T::decode(r)?)
28 } else {
29 None
30 })
31 }
32}
33
34impl Encode for Uuid {
35 fn encode(&self, w: impl Write) -> anyhow::Result<()> {
36 self.as_u128().encode(w)
37 }
38}
39
40impl<'a> Decode<'a> for Uuid {
41 fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
42 u128::decode(r).map(Uuid::from_u128)
43 }
44}
45
46impl Encode for Compound {
47 fn encode(&self, w: impl Write) -> anyhow::Result<()> {
48 Ok(valence_nbt::to_binary(self, w, "")?)
49 }
50}
51
52impl Decode<'_> for Compound {
53 fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
54 if r.first() == Some(&0) {
56 *r = &r[1..];
57 return Ok(Compound::new());
58 }
59
60 Ok(valence_nbt::from_binary(r)?.0)
63 }
64}
65
66impl<S: Encode> Encode for Ident<S> {
67 fn encode(&self, w: impl Write) -> anyhow::Result<()> {
68 self.as_ref().encode(w)
69 }
70}
71
72impl<'a, S> Decode<'a> for Ident<S>
73where
74 S: Decode<'a>,
75 Ident<S>: TryFrom<S, Error = IdentError>,
76{
77 fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
78 Ok(Ident::try_from(S::decode(r)?)?)
79 }
80}
81
82impl Encode for BlockState {
83 fn encode(&self, w: impl Write) -> anyhow::Result<()> {
84 VarInt(i32::from(self.to_raw())).encode(w)
85 }
86}
87
88impl Decode<'_> for BlockState {
89 fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
90 let id = VarInt::decode(r)?.0;
91 let errmsg = "invalid block state ID";
92
93 BlockState::from_raw(id.try_into().context(errmsg)?).context(errmsg)
94 }
95}
96
97impl Encode for BlockKind {
98 fn encode(&self, w: impl Write) -> anyhow::Result<()> {
99 VarInt(i32::from(self.to_raw())).encode(w)
100 }
101}
102
103impl Decode<'_> for BlockKind {
104 fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
105 let id = VarInt::decode(r)?.0;
106 let errmsg = "invalid block kind ID";
107
108 BlockKind::from_raw(id.try_into().context(errmsg)?).context(errmsg)
109 }
110}
111
112impl Encode for BlockEntityKind {
113 fn encode(&self, w: impl Write) -> anyhow::Result<()> {
114 VarInt(self.id() as i32).encode(w)
115 }
116}
117
118impl<'a> Decode<'a> for BlockEntityKind {
119 fn decode(r: &mut &'a [u8]) -> anyhow::Result<Self> {
120 let id = VarInt::decode(r)?;
121 Self::from_id(id.0 as u32).with_context(|| format!("id {}", id.0))
122 }
123}
124
125impl Encode for ItemKind {
126 fn encode(&self, w: impl Write) -> anyhow::Result<()> {
127 VarInt(i32::from(self.to_raw())).encode(w)
128 }
129}
130
131impl Decode<'_> for ItemKind {
132 fn decode(r: &mut &[u8]) -> anyhow::Result<Self> {
133 let id = VarInt::decode(r)?.0;
134 let errmsg = "invalid item ID";
135
136 ItemKind::from_raw(id.try_into().context(errmsg)?).context(errmsg)
137 }
138}