1use crate::buffer::OutputTarget;
4use crate::encode_into::*;
5use crate::encoder::Encoder;
6use crate::{Error, InvalidDataErrorKind, Result, VARINT62_MAX, VARINT62_MIN, VARUINT62_MAX, VARUINT62_MIN};
7
8#[cfg(feature = "alloc")]
11use alloc::collections::BTreeMap;
12#[cfg(feature = "alloc")]
13use alloc::string::String;
14#[cfg(feature = "alloc")]
15use alloc::vec::Vec;
16
17#[cfg(feature = "std")]
19use std::collections::HashMap;
20
21impl EncodeInto for bool {
26 fn encode_into(self, encoder: &mut Encoder<impl OutputTarget>) -> Result<()> {
28 encoder.write_byte(self as u8)
30 }
31}
32implement_encode_into_on_borrowed_type!(bool);
33
34impl EncodeInto for u8 {
35 fn encode_into(self, encoder: &mut Encoder<impl OutputTarget>) -> Result<()> {
37 encoder.write_byte(self)
38 }
39}
40implement_encode_into_on_borrowed_type!(u8);
41
42impl EncodeInto for i8 {
43 fn encode_into(self, encoder: &mut Encoder<impl OutputTarget>) -> Result<()> {
45 encoder.write_byte(self as u8)
47 }
48}
49implement_encode_into_on_borrowed_type!(i8);
50
51implement_encode_into_on_numeric_primitive_type! {u16, "Encodes this [`u16`] on 2 bytes (little endian)."}
52implement_encode_into_on_numeric_primitive_type! {i16, "Encodes this [`i16`] on 2 bytes (little endian) in two's complement form."}
53implement_encode_into_on_numeric_primitive_type! {u32, "Encodes this [`u32`] on 4 bytes (little endian)."}
54implement_encode_into_on_numeric_primitive_type! {i32, "Encodes this [`i32`] on 4 bytes (little endian) in two's complement form."}
55implement_encode_into_on_numeric_primitive_type! {u64, "Encodes this [`u64`] on 8 bytes (little endian)."}
56implement_encode_into_on_numeric_primitive_type! {i64, "Encodes this [`i64`] on 8 bytes (little endian) in two's complement form."}
57implement_encode_into_on_numeric_primitive_type! {f32, "Encodes this [`f32`] on 4 bytes (little endian) using the \"binary32\" representation defined in IEEE 754-2008."}
58implement_encode_into_on_numeric_primitive_type! {f64, "Encodes this [`f64`] on 8 bytes (little endian) using the \"binary64\" representation defined in IEEE 754-2008."}
59
60fn varint_range_error(value: impl Into<i128>) -> Error {
66 let error = InvalidDataErrorKind::OutOfRange {
67 value: value.into(),
68 min: VARINT62_MIN as i128,
69 max: VARINT62_MAX as i128,
70 typename: "varint62",
71 };
72 error.into()
73}
74
75fn varuint_range_error(value: impl Into<i128>) -> Error {
77 let error = InvalidDataErrorKind::OutOfRange {
78 value: value.into(),
79 min: VARUINT62_MIN as i128,
80 max: VARUINT62_MAX as i128,
81 typename: "varuint62",
82 };
83 error.into()
84}
85
86impl<O: OutputTarget> Encoder<O> {
87 #[rustfmt::skip] pub fn encode_varint(&mut self, value: impl Into<i64>) -> Result<()> {
92 let value: i64 = value.into();
93
94 let mut required_bits = i64::BITS - match value.is_negative() {
98 false => value.leading_zeros(),
100 true => value.leading_ones(),
102 };
103 required_bits += 1; let shifted_value: i64 = value << 2;
106
107 match required_bits {
108 0..=6 => self.encode(shifted_value as i8),
109 7..=14 => self.encode(shifted_value as i16 | 0b01),
110 15..=30 => self.encode(shifted_value as i32 | 0b10),
111 31..=62 => self.encode(shifted_value | 0b11),
112 63.. => Err(varint_range_error(value)),
113 }
114 }
115
116 #[rustfmt::skip] pub fn encode_varuint(&mut self, value: impl Into<u64>) -> Result<()> {
121 let value: u64 = value.into();
122
123 let required_bits = u64::BITS - value.leading_zeros();
127 let shifted_value: u64 = value << 2;
129
130 match required_bits {
131 0..=6 => self.encode(shifted_value as u8),
132 7..=14 => self.encode(shifted_value as u16 | 0b01),
133 15..=30 => self.encode(shifted_value as u32 | 0b10),
134 31..=62 => self.encode(shifted_value | 0b11),
135 63.. => Err(varuint_range_error(value)),
136 }
137 }
138
139 pub fn encode_size(&mut self, value: usize) -> Result<()> {
141 let size = u64::try_from(value)?;
142 self.encode_varuint(size)
143 }
144}
145
146impl EncodeInto for &str {
152 fn encode_into(self, encoder: &mut Encoder<impl OutputTarget>) -> Result<()> {
153 encoder.encode_size(self.len())?;
154 encoder.write_bytes_exact(self.as_bytes())
155 }
156}
157
158#[cfg(feature = "alloc")]
159impl EncodeInto for &String {
160 fn encode_into(self, encoder: &mut Encoder<impl OutputTarget>) -> Result<()> {
161 self.as_str().encode_into(encoder)
162 }
163}
164
165impl<'a, T> EncodeInto for &'a [T]
167where
168 &'a T: EncodeInto,
169{
170 fn encode_into(self, encoder: &mut Encoder<impl OutputTarget>) -> Result<()> {
171 encoder.encode_size(self.len())?;
172 for element in self {
173 encoder.encode(element)?;
174 }
175 Ok(())
176 }
177}
178
179#[cfg(feature = "alloc")]
180impl<'a, T> EncodeInto for &'a Vec<T>
181where
182 &'a T: EncodeInto,
183{
184 fn encode_into(self, encoder: &mut Encoder<impl OutputTarget>) -> Result<()> {
185 self.as_slice().encode_into(encoder)
186 }
187}
188
189#[cfg(feature = "alloc")]
194impl_encode_into_on_dictionary_type!(BTreeMap, "TODO");
195
196#[cfg(feature = "std")]
197impl_encode_into_on_dictionary_type!(HashMap, "TODO");
198
199