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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
use crate::value_kind::*;
use crate::*;

categorize_simple!(i8, ValueKind::I8);
categorize_simple!(i16, ValueKind::I16);
categorize_simple!(i32, ValueKind::I32);
categorize_simple!(i64, ValueKind::I64);
categorize_simple!(i128, ValueKind::I128);
categorize_simple!(isize, ValueKind::I64);
categorize_simple!(u8, ValueKind::U8);
categorize_simple!(u16, ValueKind::U16);
categorize_simple!(u32, ValueKind::U32);
categorize_simple!(u64, ValueKind::U64);
categorize_simple!(u128, ValueKind::U128);
categorize_simple!(usize, ValueKind::U64);

impl<X: CustomValueKind, E: Encoder<X>> Encode<X, E> for i8 {
    #[inline]
    fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
        encoder.write_value_kind(Self::value_kind())
    }

    #[inline]
    fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
        encoder.write_byte(*self as u8)
    }
}

impl<X: CustomValueKind, E: Encoder<X>> Encode<X, E> for u8 {
    #[inline]
    fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
        encoder.write_value_kind(Self::value_kind())
    }

    #[inline]
    fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
        encoder.write_byte(*self)
    }
}

macro_rules! encode_int {
    ($type:ident, $value_kind:ident) => {
        impl<X: CustomValueKind, E: Encoder<X>> Encode<X, E> for $type {
            #[inline]
            fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
                encoder.write_value_kind(Self::value_kind())
            }

            #[inline]
            fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
                encoder.write_slice(&(*self).to_le_bytes())
            }
        }
    };
}

encode_int!(i16, VALUE_KIND_I16);
encode_int!(i32, VALUE_KIND_I32);
encode_int!(i64, VALUE_KIND_I64);
encode_int!(i128, VALUE_KIND_I128);
encode_int!(u16, VALUE_KIND_U16);
encode_int!(u32, VALUE_KIND_U32);
encode_int!(u64, VALUE_KIND_U64);
encode_int!(u128, VALUE_KIND_U128);

impl<X: CustomValueKind, E: Encoder<X>> Encode<X, E> for isize {
    #[inline]
    fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
        encoder.write_value_kind(Self::value_kind())
    }

    #[inline]
    fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
        (*self as i64).encode_body(encoder)
    }
}

impl<X: CustomValueKind, E: Encoder<X>> Encode<X, E> for usize {
    #[inline]
    fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
        encoder.write_value_kind(Self::value_kind())
    }

    #[inline]
    fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
        (*self as u64).encode_body(encoder)
    }
}

impl<X: CustomValueKind, D: Decoder<X>> Decode<X, D> for i8 {
    #[inline]
    fn decode_body_with_value_kind(
        decoder: &mut D,
        value_kind: ValueKind<X>,
    ) -> Result<Self, DecodeError> {
        decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
        let value = decoder.read_byte()?;
        Ok(value as i8)
    }
}

impl<X: CustomValueKind, D: Decoder<X>> Decode<X, D> for u8 {
    #[inline]
    fn decode_body_with_value_kind(
        decoder: &mut D,
        value_kind: ValueKind<X>,
    ) -> Result<Self, DecodeError> {
        decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
        let value = decoder.read_byte()?;
        Ok(value)
    }
}

macro_rules! decode_int {
    ($type:ident, $value_kind:ident, $n:expr) => {
        impl<X: CustomValueKind, D: Decoder<X>> Decode<X, D> for $type {
            #[inline]
            fn decode_body_with_value_kind(
                decoder: &mut D,
                value_kind: ValueKind<X>,
            ) -> Result<Self, DecodeError> {
                decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
                let slice = decoder.read_slice($n)?;
                let mut bytes = [0u8; $n];
                bytes.copy_from_slice(&slice[..]);
                Ok(<$type>::from_le_bytes(bytes))
            }
        }
    };
}

decode_int!(i16, VALUE_KIND_I16, 2);
decode_int!(i32, VALUE_KIND_I32, 4);
decode_int!(i64, VALUE_KIND_I64, 8);
decode_int!(i128, VALUE_KIND_I128, 16);
decode_int!(u16, VALUE_KIND_U16, 2);
decode_int!(u32, VALUE_KIND_U32, 4);
decode_int!(u64, VALUE_KIND_U64, 8);
decode_int!(u128, VALUE_KIND_U128, 16);

impl<X: CustomValueKind, D: Decoder<X>> Decode<X, D> for isize {
    #[inline]
    fn decode_body_with_value_kind(
        decoder: &mut D,
        value_kind: ValueKind<X>,
    ) -> Result<Self, DecodeError> {
        decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
        i64::decode_body_with_value_kind(decoder, value_kind).map(|i| i as isize)
    }
}

impl<X: CustomValueKind, D: Decoder<X>> Decode<X, D> for usize {
    #[inline]
    fn decode_body_with_value_kind(
        decoder: &mut D,
        value_kind: ValueKind<X>,
    ) -> Result<Self, DecodeError> {
        decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
        u64::decode_body_with_value_kind(decoder, value_kind).map(|i| i as usize)
    }
}

mod schema {
    use super::*;

    describe_basic_well_known_type!(u8, U8_TYPE, u8_type_data);
    describe_basic_well_known_type!(u16, U16_TYPE, u16_type_data);
    describe_basic_well_known_type!(u32, U32_TYPE, u32_type_data);
    describe_basic_well_known_type!(u64, U64_TYPE, u64_type_data);
    describe_basic_well_known_type!(u128, U128_TYPE, u128_type_data);
    describe_basic_well_known_type!(i8, I8_TYPE, i8_type_data);
    describe_basic_well_known_type!(i16, I16_TYPE, i16_type_data);
    describe_basic_well_known_type!(i32, I32_TYPE, i32_type_data);
    describe_basic_well_known_type!(i64, I64_TYPE, i64_type_data);
    describe_basic_well_known_type!(i128, I128_TYPE, i128_type_data);

    describe_basic_well_known_type!(usize, U64_TYPE, u64_type_data);
    describe_basic_well_known_type!(isize, I64_TYPE, i64_type_data);
}