restless_core/
data.rs

1//! Traits to encode and decode request and response bodies.
2
3#[cfg(feature = "bytes")]
4use bytes::Bytes;
5use std::borrow::Cow;
6use std::{convert::Infallible, error::Error};
7
8/// Determines how a response is decoded.
9pub trait Decodable: Sized {
10    /// Target type to decode to.
11    type Target;
12
13    /// Error which can occur when attempting to decode data.
14    type Error: Error + Sync + Send + 'static;
15
16    /// Decode data from a byte slice.
17    fn decode(data: &[u8]) -> Result<Self::Target, Self::Error>;
18
19    #[cfg(feature = "bytes")]
20    /// Decode data from [`Bytes`].
21    fn decode_bytes(data: Bytes) -> Result<Self::Target, Self::Error> {
22        Self::decode(&data[..])
23    }
24}
25
26#[cfg(feature = "bytes")]
27impl Decodable for Bytes {
28    type Target = Bytes;
29    type Error = Infallible;
30
31    fn decode(data: &[u8]) -> Result<Self::Target, Self::Error> {
32        Ok(data.to_vec().into())
33    }
34
35    fn decode_bytes(data: Bytes) -> Result<Self::Target, Self::Error> {
36        Ok(data.clone())
37    }
38}
39
40/// Error decoding a body which should be empty.
41#[derive(thiserror::Error, Debug)]
42pub enum EmptyDecodeError {
43    /// Body is not empty.
44    #[error("body is not empty")]
45    NotEmpty,
46}
47
48impl Decodable for () {
49    type Target = ();
50    type Error = EmptyDecodeError;
51
52    fn decode(data: &[u8]) -> Result<Self::Target, Self::Error> {
53        if !data.is_empty() {
54            return Err(EmptyDecodeError::NotEmpty);
55        }
56
57        Ok(())
58    }
59}
60
61impl Decodable for Vec<u8> {
62    type Target = Self;
63    type Error = Infallible;
64
65    fn decode(data: &[u8]) -> Result<Self::Target, Self::Error> {
66        Ok(data.to_vec())
67    }
68}
69
70/// Determines how a request is encoded.
71pub trait Encodable {
72    /// Encode self into a byte array.
73    fn encode(&self) -> Vec<u8>;
74
75    #[cfg(feature = "bytes")]
76    /// Encode self into [`Bytes`].
77    fn encode_bytes(&self) -> Bytes {
78        self.encode().into()
79    }
80
81    /// Content type of this data.
82    fn content_type(&self) -> Option<Cow<'_, str>> {
83        None
84    }
85}
86
87impl Encodable for () {
88    fn encode(&self) -> Vec<u8> {
89        Vec::new()
90    }
91}
92
93#[cfg(feature = "bytes")]
94impl Encodable for Bytes {
95    fn encode(&self) -> Vec<u8> {
96        self.to_vec()
97    }
98
99    fn encode_bytes(&self) -> Bytes {
100        self.clone()
101    }
102}