1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::{Decoder, Encoder};
use thiserror::Error;

#[derive(Debug, Error)]
pub enum HybridCoderError<E> {
    #[error("Not implemented: {0}")]
    NotImplemented(&'static str),
    #[error("Decoding error")]
    Coder(#[from] E),
}

pub trait HybridDecoder<T, E: ?Sized> {
    type Error;

    fn is_binary_decoder() -> bool;

    fn decode_str(_val: &str) -> Result<T, HybridCoderError<Self::Error>> {
        Err(HybridCoderError::NotImplemented(
            "You're trying to decode from a string. This codec is binary.",
        ))
    }

    fn decode_bin(_val: &[u8]) -> Result<T, HybridCoderError<Self::Error>> {
        Err(HybridCoderError::NotImplemented(
            "You're trying to decode from a byte slice. This codec is a string codec.",
        ))
    }
}

impl<T, D> HybridDecoder<T, [u8]> for D
where
    D: Decoder<T, Encoded = [u8]>,
{
    type Error = D::Error;

    #[inline(always)]
    fn is_binary_decoder() -> bool {
        true
    }

    fn decode_bin(val: &[u8]) -> Result<T, HybridCoderError<Self::Error>> {
        Ok(D::decode(val)?)
    }
}

impl<T, D> HybridDecoder<T, str> for D
where
    D: Decoder<T, Encoded = str>,
{
    type Error = D::Error;

    #[inline(always)]
    fn is_binary_decoder() -> bool {
        false
    }

    fn decode_str(val: &str) -> Result<T, HybridCoderError<Self::Error>> {
        Ok(D::decode(val)?)
    }
}

pub trait HybridEncoder<T, E> {
    type Error;

    fn is_binary_encoder() -> bool;

    fn encode_str(_val: &T) -> Result<String, HybridCoderError<Self::Error>> {
        Err(HybridCoderError::NotImplemented(
            "You're trying to encode into a string. This codec is binary.",
        ))
    }

    fn encode_bin(_val: &T) -> Result<Vec<u8>, HybridCoderError<Self::Error>> {
        Err(HybridCoderError::NotImplemented(
            "You're trying to encode into a byte vec. This codec is a string codec.",
        ))
    }
}

impl<T, E> HybridEncoder<T, Vec<u8>> for E
where
    E: Encoder<T, Encoded = Vec<u8>>,
{
    type Error = E::Error;

    #[inline(always)]
    fn is_binary_encoder() -> bool {
        true
    }

    fn encode_bin(val: &T) -> Result<Vec<u8>, HybridCoderError<Self::Error>> {
        Ok(E::encode(val)?)
    }
}

impl<T, E> HybridEncoder<T, String> for E
where
    E: Encoder<T, Encoded = String>,
{
    type Error = E::Error;

    #[inline(always)]
    fn is_binary_encoder() -> bool {
        false
    }

    fn encode_str(val: &T) -> Result<String, HybridCoderError<Self::Error>> {
        Ok(E::encode(val)?)
    }
}