btt 0.5.0

Binary to text encodings
Documentation
macro_rules! impl_encoding {
	($encoder:ident, $decoder:ident, $len:literal, $encoder_impl:ident, $decoder_impl:ident) => {
		use crate::{
			DecodeIntoExactError, Decoder, DynDecoder, DynEncoder, EncodeIntoExactError, Encoder,
			alphabet::{Alphabet, DecodingTable, DynAlphabet, DynDecodingTable},
			generic::{GenericDecoder, GenericEncoder},
			padding::Padding
		};

		pub type $encoder<A, D, P> = GenericEncoder<A, D, P, $len>;
		pub type $decoder<D, P> = GenericDecoder<D, P, $len>;

		impl<A, D, P> Encoder<$len> for $encoder<A, D, P>
		where
			A: AsRef<Alphabet<$len>> + Copy,
			D: AsRef<DecodingTable<$len>> + Copy,
			P: Padding
		{
			fn alphabet(&self) -> &Alphabet<$len> {
				self.as_ref()
			}
		}

		impl<A, D, P> DynEncoder for $encoder<A, D, P>
		where
			A: AsRef<Alphabet<$len>> + Copy,
			D: AsRef<DecodingTable<$len>> + Copy,
			P: Padding
		{
			fn dyn_alphabet(&self) -> &DynAlphabet {
				self.alphabet().as_ref().as_dyn_alphabet()
			}

			fn encoded_len(&self, len: usize) -> Option<usize> {
				$encoder_impl::from(*self).encoded_len(len)
			}

			fn encode_into_exact<'a>(
				&self,
				src: &[u8],
				dst: &'a mut [u8]
			) -> Result<&'a str, EncodeIntoExactError> {
				$encoder_impl::from(*self).encode_into_exact(src, dst)
			}
		}

		impl<A, D, P> Decoder<$len> for $encoder<A, D, P>
		where
			A: AsRef<Alphabet<$len>> + Copy,
			D: AsRef<DecodingTable<$len>> + Copy,
			P: Padding
		{
			fn decoding_table(&self) -> &DecodingTable<$len> {
				self.as_ref()
			}
		}

		impl<A, D, P> DynDecoder for $encoder<A, D, P>
		where
			A: AsRef<Alphabet<$len>> + Copy,
			D: AsRef<DecodingTable<$len>> + Copy,
			P: Padding
		{
			fn dyn_decoding_table(&self) -> &DynDecodingTable {
				self.decoding_table().as_ref().as_dyn_decoding_table()
			}

			fn decoded_len(&self, src: &[u8]) -> Option<usize> {
				$decoder::from(*self).decoded_len(src)
			}

			fn decode_into_exact<'a>(
				&self,
				src: &[u8],
				dst: &'a mut [u8]
			) -> Result<&'a [u8], DecodeIntoExactError> {
				$decoder::from(*self).decode_into_exact(src, dst)
			}
		}

		impl<D, P> Decoder<$len> for $decoder<D, P>
		where
			D: AsRef<DecodingTable<$len>> + Copy,
			P: Padding
		{
			fn decoding_table(&self) -> &DecodingTable<$len> {
				self.as_ref()
			}
		}

		impl<D, P> DynDecoder for $decoder<D, P>
		where
			D: AsRef<DecodingTable<$len>> + Copy,
			P: Padding
		{
			fn dyn_decoding_table(&self) -> &DynDecodingTable {
				self.decoding_table().as_ref().as_dyn_decoding_table()
			}

			fn decoded_len(&self, src: &[u8]) -> Option<usize> {
				$decoder_impl::from(*self).decoded_len(src)
			}

			fn decode_into_exact<'a>(
				&self,
				src: &[u8],
				dst: &'a mut [u8]
			) -> Result<&'a [u8], DecodeIntoExactError> {
				$decoder_impl::from(*self).decode_into_exact(src, dst)
			}
		}
	};
}

macro_rules! impl_encoder {
	($name:ident, $len:literal, $alphabet:literal, $decoding_table:expr, $padding:ident) => {
		#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
		pub struct $name;

		impl $name {
			pub const ALPHABET: &Alphabet<$len> = unsafe { Alphabet::new_unchecked($alphabet) };
			pub const DECODING_TABLE: &DecodingTable<$len> = &$decoding_table;
		}

		impl AsRef<Alphabet<$len>> for $name {
			#[inline]
			fn as_ref(&self) -> &Alphabet<$len> {
				Self::ALPHABET
			}
		}

		impl AsRef<DecodingTable<$len>> for $name {
			#[inline]
			fn as_ref(&self) -> &DecodingTable<$len> {
				Self::DECODING_TABLE
			}
		}

		impl From<$name> for GenericEncoder<$name, $name, $padding, $len> {
			#[inline]
			fn from(_: $name) -> Self {
				unsafe { Self::new_unchecked($name, $name, $padding) }
			}
		}

		impl From<$name> for GenericDecoder<$name, $padding, $len> {
			#[inline]
			fn from(_: $name) -> Self {
				unsafe { Self::new_unchecked($name, $padding) }
			}
		}

		impl Encoder<$len> for $name {
			fn alphabet(&self) -> &Alphabet<$len> {
				self.as_ref()
			}
		}

		impl DynEncoder for $name {
			#[inline]
			fn dyn_alphabet(&self) -> &DynAlphabet {
				Self::ALPHABET.as_dyn_alphabet()
			}

			#[inline]
			fn encoded_len(&self, len: usize) -> Option<usize> {
				GenericEncoder::from($name).encoded_len(len)
			}

			#[inline]
			fn encode_into_exact<'a>(
				&self,
				src: &[u8],
				dst: &'a mut [u8]
			) -> Result<&'a str, EncodeIntoExactError> {
				GenericEncoder::from($name).encode_into_exact(src, dst)
			}
		}

		impl Decoder<$len> for $name {
			fn decoding_table(&self) -> &DecodingTable<$len> {
				self.as_ref()
			}
		}

		impl DynDecoder for $name {
			#[inline]
			fn dyn_decoding_table(&self) -> &DynDecodingTable {
				Self::DECODING_TABLE.as_dyn_decoding_table()
			}

			#[inline]
			fn decoded_len(&self, src: &[u8]) -> Option<usize> {
				GenericDecoder::from($name).decoded_len(src)
			}

			#[inline]
			fn decode_into_exact<'a>(
				&self,
				src: &[u8],
				dst: &'a mut [u8]
			) -> Result<&'a [u8], DecodeIntoExactError> {
				GenericDecoder::from($name).decode_into_exact(src, dst)
			}
		}
	};

	($name:ident, $len:literal, $alphabet:literal, $padding:ident) => {
		impl_encoder!($name, $len, $alphabet, Self::ALPHABET.decoding_table(), $padding);
	};
}