1use std::{borrow::Cow, sync::Arc};
2
3use bytes::{Bytes, BytesMut};
4
5use super::BoundsExceeded;
6
7#[derive(thiserror::Error, Debug, Clone)]
9#[non_exhaustive]
10pub enum EncodeError {
11 #[error("bounds exceeded")]
13 BoundsExceeded,
14 #[error("too large")]
16 TooLarge,
17 #[error("short buffer")]
19 Short,
20 #[error("invalid state")]
22 InvalidState,
23 #[error("too many")]
25 TooMany,
26 #[error("unsupported version")]
28 Version,
29 #[error("unsupported")]
31 Unsupported,
32}
33
34impl From<BoundsExceeded> for EncodeError {
35 fn from(_: BoundsExceeded) -> Self {
36 Self::BoundsExceeded
37 }
38}
39
40fn check_remaining(w: &impl bytes::BufMut, needed: usize) -> Result<(), EncodeError> {
42 if w.remaining_mut() < needed {
43 return Err(EncodeError::Short);
44 }
45 Ok(())
46}
47
48pub trait Encode<V>: Sized {
50 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError>;
52
53 fn encode_bytes(&self, v: V) -> Result<Bytes, EncodeError> {
57 let mut buf = BytesMut::new();
58 self.encode(&mut buf, v)?;
59 Ok(buf.freeze())
60 }
61}
62
63impl<V> Encode<V> for bool {
64 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) -> Result<(), EncodeError> {
65 check_remaining(&*w, 1)?;
66 w.put_u8(*self as u8);
67 Ok(())
68 }
69}
70
71impl<V> Encode<V> for u8 {
72 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) -> Result<(), EncodeError> {
73 check_remaining(&*w, 1)?;
74 w.put_u8(*self);
75 Ok(())
76 }
77}
78
79impl<V> Encode<V> for u16 {
80 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) -> Result<(), EncodeError> {
81 check_remaining(&*w, 2)?;
82 w.put_u16(*self);
83 Ok(())
84 }
85}
86
87impl<V: Copy> Encode<V> for String
88where
89 usize: Encode<V>,
90{
91 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
92 self.as_str().encode(w, version)
93 }
94}
95
96impl<V: Copy> Encode<V> for &str
97where
98 usize: Encode<V>,
99{
100 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
101 self.len().encode(w, version)?;
102 check_remaining(&*w, self.len())?;
103 w.put(self.as_bytes());
104 Ok(())
105 }
106}
107
108impl<V> Encode<V> for i8 {
109 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) -> Result<(), EncodeError> {
110 check_remaining(&*w, 1)?;
114 w.put_u8(((*self as i16) + 128) as u8);
115 Ok(())
116 }
117}
118
119impl<V: Copy, T: Encode<V>> Encode<V> for &[T]
120where
121 usize: Encode<V>,
122{
123 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
124 self.len().encode(w, version)?;
125 for item in self.iter() {
126 item.encode(w, version)?;
127 }
128 Ok(())
129 }
130}
131
132impl<V: Copy> Encode<V> for Vec<u8>
133where
134 usize: Encode<V>,
135{
136 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
137 self.len().encode(w, version)?;
138 check_remaining(&*w, self.len())?;
139 w.put_slice(self);
140 Ok(())
141 }
142}
143
144impl<V: Copy> Encode<V> for bytes::Bytes
145where
146 usize: Encode<V>,
147{
148 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
149 self.len().encode(w, version)?;
150 check_remaining(&*w, self.len())?;
151 w.put_slice(self);
152 Ok(())
153 }
154}
155
156impl<T: Encode<V>, V> Encode<V> for Arc<T> {
157 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
158 (**self).encode(w, version)
159 }
160}
161
162impl<V: Copy> Encode<V> for Cow<'_, str>
163where
164 usize: Encode<V>,
165{
166 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
167 self.len().encode(w, version)?;
168 check_remaining(&*w, self.len())?;
169 w.put(self.as_bytes());
170 Ok(())
171 }
172}
173
174impl<V: Copy> Encode<V> for Option<u64>
175where
176 u64: Encode<V>,
177{
178 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
179 match self {
180 Some(value) => value.checked_add(1).ok_or(EncodeError::TooLarge)?.encode(w, version),
181 None => 0u64.encode(w, version),
182 }
183 }
184}
185
186impl<V: Copy> Encode<V> for std::time::Duration
187where
188 super::VarInt: Encode<V>,
189{
190 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
191 let ms = super::VarInt::try_from(self.as_millis())?;
192 ms.encode(w, version)
193 }
194}