use super::{write::Writer, Encode, Encoder}; use crate::{ config::{ Endian, IntEncoding, InternalArrayLengthConfig, InternalEndianConfig, InternalIntEncodingConfig, }, error::EncodeError, }; use core::{ cell::{Cell, RefCell}, marker::PhantomData, num::{ NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, }, ops::{Bound, Range, RangeInclusive}, time::Duration, }; impl Encode for () { fn encode(&self, _: &mut E) -> Result<(), EncodeError> { Ok(()) } } impl Encode for PhantomData { fn encode(&self, _: &mut E) -> Result<(), EncodeError> { Ok(()) } } impl Encode for bool { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { if *self { 1u8 } else { 0u8 }.encode(encoder) } } impl Encode for u8 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { encoder.writer().write(&[*self]) } } impl Encode for NonZeroU8 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for u16 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_u16(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), }, } } } impl Encode for NonZeroU16 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for u32 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_u32(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), }, } } } impl Encode for NonZeroU32 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for u64 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_u64(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), }, } } } impl Encode for NonZeroU64 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for u128 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_u128(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), }, } } } impl Encode for NonZeroU128 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for usize { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_usize(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&(*self as u64).to_be_bytes()), Endian::Little => encoder.writer().write(&(*self as u64).to_le_bytes()), }, } } } impl Encode for NonZeroUsize { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for i8 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { encoder.writer().write(&[*self as u8]) } } impl Encode for NonZeroI8 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for i16 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_i16(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), }, } } } impl Encode for NonZeroI16 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for i32 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_i32(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), }, } } } impl Encode for NonZeroI32 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for i64 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_i64(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), }, } } } impl Encode for NonZeroI64 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for i128 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_i128(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), }, } } } impl Encode for NonZeroI128 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for isize { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::INT_ENCODING { IntEncoding::Variable => { crate::varint::varint_encode_isize(encoder.writer(), E::C::ENDIAN, *self) } IntEncoding::Fixed => match E::C::ENDIAN { Endian::Big => encoder.writer().write(&(*self as i64).to_be_bytes()), Endian::Little => encoder.writer().write(&(*self as i64).to_le_bytes()), }, } } } impl Encode for NonZeroIsize { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.get().encode(encoder) } } impl Encode for f32 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), } } } impl Encode for f64 { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match E::C::ENDIAN { Endian::Big => encoder.writer().write(&self.to_be_bytes()), Endian::Little => encoder.writer().write(&self.to_le_bytes()), } } } impl Encode for char { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { encode_utf8(encoder.writer(), *self) } } // impl Encode for &'_ [u8] { // fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { // super::encode_slice_len(encoder, self.len())?; // encoder.writer().write(self) // } // } const TAG_CONT: u8 = 0b1000_0000; const TAG_TWO_B: u8 = 0b1100_0000; const TAG_THREE_B: u8 = 0b1110_0000; const TAG_FOUR_B: u8 = 0b1111_0000; const MAX_ONE_B: u32 = 0x80; const MAX_TWO_B: u32 = 0x800; const MAX_THREE_B: u32 = 0x10000; fn encode_utf8(writer: &mut impl Writer, c: char) -> Result<(), EncodeError> { let code = c as u32; if code < MAX_ONE_B { writer.write(&[c as u8]) } else if code < MAX_TWO_B { let mut buf = [0u8; 2]; buf[0] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; buf[1] = (code & 0x3F) as u8 | TAG_CONT; writer.write(&buf) } else if code < MAX_THREE_B { let mut buf = [0u8; 3]; buf[0] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; buf[1] = (code >> 6 & 0x3F) as u8 | TAG_CONT; buf[2] = (code & 0x3F) as u8 | TAG_CONT; writer.write(&buf) } else { let mut buf = [0u8; 4]; buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT; buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; buf[3] = (code & 0x3F) as u8 | TAG_CONT; writer.write(&buf) } } // BlockedTODO: https://github.com/rust-lang/rust/issues/37653 // // We'll want to implement encoding for both &[u8] and &[T: Encode], // but those implementations overlap because u8 also implements Encode // impl Encode for &'_ [u8] { // fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { // encoder.writer().write(*self) // } // } impl Encode for &'_ [T] { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.len().encode(encoder)?; for item in self.iter() { item.encode(encoder)?; } Ok(()) } } impl Encode for str { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.as_bytes().encode(encoder) } } impl Encode for [T; N] where T: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { if !E::C::SKIP_FIXED_ARRAY_LENGTH { super::encode_slice_len(encoder, N)?; } for item in self.iter() { item.encode(encoder)?; } Ok(()) } } impl Encode for Option where T: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { super::encode_option_variant(encoder, self)?; if let Some(val) = self { val.encode(encoder)?; } Ok(()) } } impl Encode for Result where T: Encode, U: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match self { Ok(val) => { 0u32.encode(encoder)?; val.encode(encoder) } Err(err) => { 1u32.encode(encoder)?; err.encode(encoder) } } } } impl Encode for Cell where T: Encode + Copy, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { T::encode(&self.get(), encoder) } } impl Encode for RefCell where T: Encode + ?Sized, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { let borrow_guard = self .try_borrow() .map_err(|e| EncodeError::RefCellAlreadyBorrowed { inner: e, type_name: core::any::type_name::>(), })?; T::encode(&borrow_guard, encoder) } } impl Encode for Duration { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.as_secs().encode(encoder)?; self.subsec_nanos().encode(encoder)?; Ok(()) } } impl Encode for Range where T: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.start.encode(encoder)?; self.end.encode(encoder)?; Ok(()) } } impl Encode for RangeInclusive where T: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.start().encode(encoder)?; self.end().encode(encoder)?; Ok(()) } } impl Encode for Bound where T: Encode, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { match self { Self::Unbounded => { 0u32.encode(encoder)?; } Self::Included(val) => { 1u32.encode(encoder)?; val.encode(encoder)?; } Self::Excluded(val) => { 2u32.encode(encoder)?; val.encode(encoder)?; } } Ok(()) } } impl<'a, T> Encode for &'a T where T: Encode + ?Sized, { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { T::encode(self, encoder) } }