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}
30
31impl From<BoundsExceeded> for EncodeError {
32 fn from(_: BoundsExceeded) -> Self {
33 Self::BoundsExceeded
34 }
35}
36
37fn check_remaining(w: &impl bytes::BufMut, needed: usize) -> Result<(), EncodeError> {
39 if w.remaining_mut() < needed {
40 return Err(EncodeError::Short);
41 }
42 Ok(())
43}
44
45pub trait Encode<V>: Sized {
47 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError>;
49
50 fn encode_bytes(&self, v: V) -> Result<Bytes, EncodeError> {
54 let mut buf = BytesMut::new();
55 self.encode(&mut buf, v)?;
56 Ok(buf.freeze())
57 }
58}
59
60impl<V> Encode<V> for bool {
61 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) -> Result<(), EncodeError> {
62 check_remaining(&*w, 1)?;
63 w.put_u8(*self as u8);
64 Ok(())
65 }
66}
67
68impl<V> Encode<V> for u8 {
69 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) -> Result<(), EncodeError> {
70 check_remaining(&*w, 1)?;
71 w.put_u8(*self);
72 Ok(())
73 }
74}
75
76impl<V> Encode<V> for u16 {
77 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) -> Result<(), EncodeError> {
78 check_remaining(&*w, 2)?;
79 w.put_u16(*self);
80 Ok(())
81 }
82}
83
84impl<V: Copy> Encode<V> for String
85where
86 usize: Encode<V>,
87{
88 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
89 self.as_str().encode(w, version)
90 }
91}
92
93impl<V: Copy> Encode<V> for &str
94where
95 usize: Encode<V>,
96{
97 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
98 self.len().encode(w, version)?;
99 check_remaining(&*w, self.len())?;
100 w.put(self.as_bytes());
101 Ok(())
102 }
103}
104
105impl<V> Encode<V> for i8 {
106 fn encode<W: bytes::BufMut>(&self, w: &mut W, _: V) -> Result<(), EncodeError> {
107 check_remaining(&*w, 1)?;
111 w.put_u8(((*self as i16) + 128) as u8);
112 Ok(())
113 }
114}
115
116impl<V: Copy, T: Encode<V>> Encode<V> for &[T]
117where
118 usize: Encode<V>,
119{
120 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
121 self.len().encode(w, version)?;
122 for item in self.iter() {
123 item.encode(w, version)?;
124 }
125 Ok(())
126 }
127}
128
129impl<V: Copy> Encode<V> for Vec<u8>
130where
131 usize: Encode<V>,
132{
133 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
134 self.len().encode(w, version)?;
135 check_remaining(&*w, self.len())?;
136 w.put_slice(self);
137 Ok(())
138 }
139}
140
141impl<V: Copy> Encode<V> for bytes::Bytes
142where
143 usize: Encode<V>,
144{
145 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
146 self.len().encode(w, version)?;
147 check_remaining(&*w, self.len())?;
148 w.put_slice(self);
149 Ok(())
150 }
151}
152
153impl<T: Encode<V>, V> Encode<V> for Arc<T> {
154 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
155 (**self).encode(w, version)
156 }
157}
158
159impl<V: Copy> Encode<V> for Cow<'_, str>
160where
161 usize: Encode<V>,
162{
163 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
164 self.len().encode(w, version)?;
165 check_remaining(&*w, self.len())?;
166 w.put(self.as_bytes());
167 Ok(())
168 }
169}
170
171impl<V: Copy> Encode<V> for Option<u64>
172where
173 u64: Encode<V>,
174{
175 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
176 match self {
177 Some(value) => value.checked_add(1).ok_or(EncodeError::TooLarge)?.encode(w, version),
178 None => 0u64.encode(w, version),
179 }
180 }
181}
182
183impl<V: Copy> Encode<V> for std::time::Duration
184where
185 super::VarInt: Encode<V>,
186{
187 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) -> Result<(), EncodeError> {
188 let ms = super::VarInt::try_from(self.as_millis())?;
189 ms.encode(w, version)
190 }
191}