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