|
12 | 12 | use std::borrow::Cow; |
13 | 13 | use std::cmp::{Ord, Ordering}; |
14 | 14 | use std::error::Error as StdError; |
| 15 | +use std::fmt; |
15 | 16 |
|
16 | 17 | /// A boxed `Send + Sync + 'static` error. |
17 | 18 | pub type BoxedError = Box<dyn StdError + Send + Sync + 'static>; |
18 | 19 |
|
19 | 20 | /// A trait that represents an encoding structure. |
20 | | -pub trait BytesEncode<'a> { |
| 21 | +#[deprecated = "replaced by `ToBytes` to allow for more optimization"] |
| 22 | +#[allow(deprecated)] // deprecated BoxedErrorWrapper is used in a bound |
| 23 | +pub trait BytesEncode<'a>: |
| 24 | + // TODO are these bound needed? |
| 25 | + ToBytes<'a, SelfType = Self::EItem, ReturnBytes = Cow<'a, [u8]>, Error = BoxedErrorWrapper> |
| 26 | +{ |
21 | 27 | /// The type to encode. |
22 | 28 | type EItem: ?Sized + 'a; |
23 | 29 |
|
24 | 30 | /// Encode the given item as bytes. |
25 | 31 | fn bytes_encode(item: &'a Self::EItem) -> Result<Cow<'a, [u8]>, BoxedError>; |
26 | 32 | } |
27 | 33 |
|
| 34 | +/// A trait that represents an encoding structure. |
| 35 | +pub trait ToBytes<'a> { |
| 36 | + /// The type to encode to bytes. |
| 37 | + type SelfType: ?Sized + 'a; |
| 38 | + |
| 39 | + /// The type containing the encoded bytes. |
| 40 | + type ReturnBytes: Into<Vec<u8>> + AsRef<[u8]> + 'a; |
| 41 | + |
| 42 | + /// The error type to return when decoding goes wrong. |
| 43 | + type Error: StdError + Send + Sync + 'static; |
| 44 | + |
| 45 | + /// Encode the given item as bytes. |
| 46 | + fn to_bytes(item: &'a Self::SelfType) -> Result<Self::ReturnBytes, Self::Error>; |
| 47 | +} |
| 48 | + |
| 49 | +#[allow(deprecated)] |
| 50 | +impl<'a, T: BytesEncode<'a>> ToBytes<'a> for T { |
| 51 | + type SelfType = <Self as BytesEncode<'a>>::EItem; |
| 52 | + |
| 53 | + type ReturnBytes = Cow<'a, [u8]>; |
| 54 | + |
| 55 | + type Error = BoxedErrorWrapper; |
| 56 | + |
| 57 | + fn to_bytes(item: &'a Self::SelfType) -> Result<Self::ReturnBytes, Self::Error> { |
| 58 | + Self::bytes_encode(item).map_err(BoxedErrorWrapper) |
| 59 | + } |
| 60 | +} |
| 61 | + |
| 62 | +/// Wraps the [`BoxedError`] type alias because for complicated reasons it does not implement |
| 63 | +/// [`Error`][StdError]. This wrapper forwards [`Debug`][fmt::Debug], [`Display`][fmt::Display] |
| 64 | +/// and [`Error`][StdError] through the wrapper and the [`Box`]. |
| 65 | +#[deprecated = "this wrapper was added for backwards compatibility of BytesEncode only"] |
| 66 | +pub struct BoxedErrorWrapper(BoxedError); |
| 67 | + |
| 68 | +#[allow(deprecated)] |
| 69 | +impl fmt::Debug for BoxedErrorWrapper { |
| 70 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 71 | + <BoxedError as fmt::Debug>::fmt(&self.0, f) |
| 72 | + } |
| 73 | +} |
| 74 | + |
| 75 | +#[allow(deprecated)] |
| 76 | +impl fmt::Display for BoxedErrorWrapper { |
| 77 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 78 | + <BoxedError as fmt::Display>::fmt(&self.0, f) |
| 79 | + } |
| 80 | +} |
| 81 | + |
| 82 | +#[allow(deprecated)] |
| 83 | +impl StdError for BoxedErrorWrapper { |
| 84 | + fn source(&self) -> Option<&(dyn StdError + 'static)> { |
| 85 | + self.0.source() |
| 86 | + } |
| 87 | +} |
| 88 | + |
28 | 89 | /// A trait that represents a decoding structure. |
29 | 90 | pub trait BytesDecode<'a> { |
30 | 91 | /// The type to decode. |
|
0 commit comments