summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer/mod.rs172
-rw-r--r--src/deserialise/mod.rs512
-rw-r--r--src/deserialise/test.rs81
-rw-r--r--src/dstream/mod.rs86
-rw-r--r--src/error/mod.rs112
-rw-r--r--src/fixed_string/mod.rs298
-rw-r--r--src/fixed_string/test.rs43
-rw-r--r--src/fixed_string_iter/mod.rs43
-rw-r--r--src/lib.rs123
-rw-r--r--src/serialise/mod.rs676
-rw-r--r--src/serialise/test.rs72
-rw-r--r--src/sstream/mod.rs103
12 files changed, 0 insertions, 2321 deletions
diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs
deleted file mode 100644
index 3ce47bd..0000000
--- a/src/buffer/mod.rs
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the impl<T: Serialise>ied warranty of MERCHANTABILITY<T> or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-use crate::{Deserialise, Dstream, Serialise, Sstream};
-
-use alloc::vec;
-use alloc::boxed::Box;
-use core::fmt::{Debug, Formatter};
-use core::marker::PhantomData;
-
-/// Container type for (de)serialisations.
-///
-/// The purpose of this type is to easily hold a buffer than can fit any serialisation of a given type (hence the generic).
-///
-/// Do note that the internal buffer does not guarantee the state of any padding bytes that occur as a result of different serialisation sizes.
-/// Deserialisations, however, are not affected by these.
-#[derive(Clone, Eq, PartialEq)]
-pub struct Buffer<T> {
- data: Box<[u8]>,
- len: usize,
-
- _phantom: PhantomData<T>,
-}
-
-impl<T> Buffer<T> {
- /// Sets the internal length of the buffer without checks.
- ///
- /// For a safe alternative, see [`set_len`](Self::set_len).
- ///
- /// # Safety
- ///
- /// The new length must **not** exceed [`T::SERIALISE_LIMIT`](Serialise::SERIALISE_LIMIT).
- #[inline(always)]
- pub unsafe fn set_len_unchecked(&mut self, len: usize) {
- self.len = len;
- }
-
- /// Returns a slice of the internal buffer.
- ///
- /// This only includes bytes written by the last serialisation, or as set by [`set_len`](Self::set_len).
- #[inline(always)]
- #[must_use]
- pub fn as_slice(&self) -> &[u8] { &self.data[0x0..self.len] }
-
- /// Returns a mutable slice of the entire internal buffer.
- ///
- /// This is in contrast to [`as_slice`](Self::as_slice), which only yields the last serialisation.
- ///
- /// The length of bytes written to this slice should be set using [`set_len`](Self::set_len).
- #[inline(always)]
- #[must_use]
- pub fn as_mut_slice(&mut self) -> &mut [u8] { self.data.as_mut() }
-}
-
-impl<T: Serialise> Buffer<T> {
- /// Constructs a new, empty buffer.
- ///
- /// The internal buffer is allocated on the heap instantly with the size [`T::SERIALISE_LIMIT`](Serialise::SERIALISE_LIMIT).
- #[inline(always)]
- #[must_use]
- pub fn new() -> Self { Self {
- data: vec![Default::default(); T::SERIALISE_LIMIT].into(),
- len: 0x0,
-
- _phantom: PhantomData
- } }
-
- /// Sets the length of the current serialisation.
- ///
- /// This is specifically meant for cases where the buffer is set externally, as is the case for networking:
- ///
- /// ```
- /// use bzipper::{Buffer, FixedString};
- /// use std::net::{SocketAddr, UdpSocket};
- /// use std::str::FromStr;
- ///
- /// let destination = SocketAddr::from_str("127.0.0.1:37279")?;
- ///
- /// let sender = UdpSocket::bind("0.0.0.0:0")?;
- /// let reciever = UdpSocket::bind(destination)?;
- ///
- /// // Create a buffer for holding a fixed string.
- /// let mut buffer = Buffer::<FixedString<0x10>>::new();
- ///
- /// // Serialise and write the string:
- /// buffer.write(&FixedString::new("Hello there!")?);
- /// sender.send_to(buffer.as_ref(), destination);
- ///
- /// // Recieve and deserialise the string:
- /// let (count, _source) = reciever.recv_from(buffer.as_mut_slice())?;
- /// buffer.set_len(count);
- ///
- /// assert_eq!(buffer.read()?, "Hello there!");
- ///
- /// # Ok::<(), Box<dyn std::error::Error>>(())
- /// ```
- ///
- /// # Panics
- ///
- /// Panics if `len` is larger than [`T::SERIALISE_LIMIT`](Serialise::SERIALISE_LIMIT).
- /// See [`set_len_unchecked`](Self::set_len_unchecked).
- #[inline]
- pub fn set_len(&mut self, len: usize) {
- assert!(len <= T::SERIALISE_LIMIT);
- self.len = len;
- }
-}
-
-impl<T: Serialise> Buffer<T> {
- /// Serialises into the buffer.
- ///
- /// The result of [`serialise`](Serialise::serialise) is used as the length.
- ///
- /// # Panics
- ///
- /// Panics if the amount of written bytes exceeds [`SERIALISE_LIMIT`](Serialise::SERIALISE_LIMIT).
- /// This *should*, in theory, not occur, as the internal buffer can only fit up to this limit, making all writes past this limit fail.
- #[allow(clippy::panic_in_result_fn)]
- pub fn write(&mut self, value: &T) -> Result<(), <T as Serialise>::Error> {
- let mut stream = Sstream::new(&mut self.data);
-
- let count = value.serialise(&mut stream)?;
- assert!(count <= T::SERIALISE_LIMIT);
-
- self.len = count;
- Ok(())
- }
-}
-
-impl<T: Deserialise> Buffer<T> {
- /// Deserialises the contained buffer.
- ///
- /// Only bytes from the last serialisation, or as set by [`set_len`](Self::set_len), are used.
- pub fn read(&self) -> Result<T, <T as Deserialise>::Error> {
- let mut stream = Dstream::new(self.as_ref());
- T::deserialise(&mut stream)
- }
-}
-
-impl<T> AsRef<[u8]> for Buffer<T> {
- #[inline(always)]
- fn as_ref(&self) -> &[u8] { self.as_slice() }
-}
-
-impl<T> Debug for Buffer<T> {
- fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
- self.data.fmt(f)
- }
-}
-
-impl<T: Serialise> Default for Buffer<T> {
- #[inline(always)]
- fn default() -> Self { Self::new() }
-}
diff --git a/src/deserialise/mod.rs b/src/deserialise/mod.rs
deleted file mode 100644
index eaebe2b..0000000
--- a/src/deserialise/mod.rs
+++ /dev/null
@@ -1,512 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-#[cfg(test)]
-mod test;
-
-use crate::{Error, Dstream};
-
-use alloc::boxed::Box;
-use core::convert::Infallible;
-use core::error::Error as StdError;
-use core::mem::{MaybeUninit, size_of};
-use core::num::NonZero;
-use core::ptr::read;
-
-/// Types capable of being deserialised.
-pub trait Deserialise: Sized {
- /// The error of deserialisation.
- ///
- /// Use [`Infallible`] if **all** deserialisations are infallible, as is the case of zero-length types.
- type Error;
-
- /// Deserialises the byte stream to an object.
- ///
- /// This function should **not** take more bytes than specified by [`T::SERIALISE_LIMIT`](crate::Serialise::SERIALISE_LIMIT).
- /// Doing so is considered a logic error.
- ///
- /// # Errors
- ///
- /// If deserialisation failed, e.g. by an invalid value being found, an error is returned.
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error>;
-}
-
-macro_rules! impl_float {
- ($type:ty) => {
- impl Deserialise for $type {
- type Error = Error;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let data = stream
- .take(size_of::<Self>())?
- .try_into()
- .unwrap();
-
- Ok(Self::from_be_bytes(data))
- }
- }
- };
-}
-
-macro_rules! impl_int {
- ($type:ty) => {
- impl Deserialise for $type {
- type Error = Error;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let data = stream
- .take(size_of::<Self>())?
- .try_into()
- .unwrap();
-
- Ok(Self::from_be_bytes(data))
- }
- }
- };
-}
-
-macro_rules! impl_non_zero {
- ($type:ty) => {
- impl Deserialise for NonZero<$type> {
- type Error = Error;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let value = <$type>::deserialise(stream)?;
-
- NonZero::new(value)
- .ok_or(Error::NullInteger)
- }
- }
- };
-}
-
-impl<T0, T1> Deserialise for (T0, T1)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2> Deserialise for (T0, T1, T2)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3> Deserialise for (T0, T1, T2, T3)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3, T4> Deserialise for (T0, T1, T2, T3, T4)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>,
- T4: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5> Deserialise for (T0, T1, T2, T3, T4, T5)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>,
- T4: Deserialise<Error: StdError + 'static>,
- T5: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6> Deserialise for (T0, T1, T2, T3, T4, T5, T6)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>,
- T4: Deserialise<Error: StdError + 'static>,
- T5: Deserialise<Error: StdError + 'static>,
- T6: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7> Deserialise for (T0, T1, T2, T3, T4, T5, T6, T7)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>,
- T4: Deserialise<Error: StdError + 'static>,
- T5: Deserialise<Error: StdError + 'static>,
- T6: Deserialise<Error: StdError + 'static>,
- T7: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> Deserialise for (T0, T1, T2, T3, T4, T5, T6, T7, T8)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>,
- T4: Deserialise<Error: StdError + 'static>,
- T5: Deserialise<Error: StdError + 'static>,
- T6: Deserialise<Error: StdError + 'static>,
- T7: Deserialise<Error: StdError + 'static>,
- T8: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> Deserialise for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>,
- T4: Deserialise<Error: StdError + 'static>,
- T5: Deserialise<Error: StdError + 'static>,
- T6: Deserialise<Error: StdError + 'static>,
- T7: Deserialise<Error: StdError + 'static>,
- T8: Deserialise<Error: StdError + 'static>,
- T9: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Deserialise for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>,
- T4: Deserialise<Error: StdError + 'static>,
- T5: Deserialise<Error: StdError + 'static>,
- T6: Deserialise<Error: StdError + 'static>,
- T7: Deserialise<Error: StdError + 'static>,
- T8: Deserialise<Error: StdError + 'static>,
- T9: Deserialise<Error: StdError + 'static>,
- T10: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Deserialise for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
-where
- T0: Deserialise<Error: StdError + 'static>,
- T1: Deserialise<Error: StdError + 'static>,
- T2: Deserialise<Error: StdError + 'static>,
- T3: Deserialise<Error: StdError + 'static>,
- T4: Deserialise<Error: StdError + 'static>,
- T5: Deserialise<Error: StdError + 'static>,
- T6: Deserialise<Error: StdError + 'static>,
- T7: Deserialise<Error: StdError + 'static>,
- T8: Deserialise<Error: StdError + 'static>,
- T9: Deserialise<Error: StdError + 'static>,
- T10: Deserialise<Error: StdError + 'static>,
- T11: Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- Ok((
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- Deserialise::deserialise(stream)?,
- ))
- }
-}
-
-impl<T, const N: usize> Deserialise for [T; N]
-where
- T: Default + Deserialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let len = usize::deserialise(stream)?;
-
- if len != N { return Err(Box::new(Error::ArrayTooShort { req: len, len: N })) };
-
- let mut buf: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
-
- // Deserialise t
- for item in buf.iter_mut().take(len) {
- item.write(Deserialise::deserialise(stream)?);
- }
-
- for item in buf.iter_mut().skip(len) {
- item.write(Default::default());
- }
-
- // This should be safe as `MaybeUninit<T>` is
- // transparent to `T`. The original buffer is
- // NOT dropped automatically, so we can just
- // forget about it from this point on.
- let buf = unsafe { read(core::ptr::from_ref(&buf).cast::<[T; N]>()) };
- Ok(buf)
- }
-}
-
-impl Deserialise for () {
- type Error = Infallible;
-
- fn deserialise(_stream: &mut Dstream) -> Result<Self, Self::Error> { Ok(()) }
-}
-
-impl Deserialise for bool {
- type Error = Error;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let value = u8::deserialise(stream)?;
-
- match value {
- 0x00 => Ok(false),
- 0x01 => Ok(true),
- _ => Err(Error::InvalidBoolean { value })
- }
- }
-}
-
-impl Deserialise for char {
- type Error = Error;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let value = u32::deserialise(stream)?;
-
- Self::from_u32(value)
- .ok_or(Error::InvalidCodePoint { value })
- }
-}
-
-impl Deserialise for Infallible {
- type Error = Self;
-
- fn deserialise(_stream: &mut Dstream) -> Result<Self, Self::Error> { unreachable!() }
-}
-
-impl Deserialise for isize {
- type Error = Error;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let value = i16::deserialise(stream)?
- .into();
-
- Ok(value)
- }
-}
-
-impl<T: Deserialise<Error: StdError + 'static>> Deserialise for Option<T> {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let sign = bool::deserialise(stream)?;
-
- if sign {
- Ok(Some(T::deserialise(stream)?))
- } else {
- Ok(None)
- }
- }
-}
-
-impl<T: Deserialise, E: Deserialise> Deserialise for Result<T, E>
-where
- <T as Deserialise>::Error: StdError + 'static,
- <E as Deserialise>::Error: StdError + 'static, {
- type Error = Box<dyn StdError>;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let sign = bool::deserialise(stream)?;
-
- let value = if sign {
- Err(E::deserialise(stream)?)
- } else {
- Ok(T::deserialise(stream)?)
- };
-
- Ok(value)
- }
-}
-
-impl Deserialise for usize {
- type Error = Error;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let value = u16::deserialise(stream)?
- .into();
-
- Ok(value)
- }
-}
-
-impl_float!(f32);
-impl_float!(f64);
-
-impl_int!(i128);
-impl_int!(i16);
-impl_int!(i32);
-impl_int!(i64);
-impl_int!(i8);
-impl_int!(u128);
-impl_int!(u16);
-impl_int!(u32);
-impl_int!(u64);
-impl_int!(u8);
-
-impl_non_zero!(i128);
-impl_non_zero!(i16);
-impl_non_zero!(i32);
-impl_non_zero!(i64);
-impl_non_zero!(i8);
-impl_non_zero!(isize);
-impl_non_zero!(u128);
-impl_non_zero!(u16);
-impl_non_zero!(u32);
-impl_non_zero!(u64);
-impl_non_zero!(u8);
-impl_non_zero!(usize);
diff --git a/src/deserialise/test.rs b/src/deserialise/test.rs
deleted file mode 100644
index e398b4d..0000000
--- a/src/deserialise/test.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-use crate::{Deserialise, Dstream, FixedString};
-
-#[test]
-fn test_deserialise() {
- let data = [
- 0x00, 0xFF, 0xFF, 0x0F, 0xEF, 0x1F, 0xDF, 0x2F,
- 0xCF, 0x3F, 0xBF, 0x4F, 0xAF, 0x5F, 0x9F, 0x6F,
- 0x8F, 0x7F, 0x00, 0x09, 0x6D, 0xC3, 0xA1, 0x6E,
- 0x61, 0xC3, 0xB0, 0x75, 0x72, 0x00, 0x05, 0x00,
- 0x00, 0x03, 0xBB, 0x00, 0x00, 0x03, 0x91, 0x00,
- 0x00, 0x03, 0xBC, 0x00, 0x00, 0x03, 0x94, 0x00,
- 0x00, 0x03, 0xB1, 0x01, 0x00, 0x00, 0x01, 0x80,
- ];
-
- let mut stream = Dstream::new(&data);
-
- assert_eq!(
- u8::deserialise(&mut stream).unwrap(),
- 0x00,
- );
- assert_eq!(
- u8::deserialise(&mut stream).unwrap(),
- 0xFF,
- );
-
- assert_eq!(
- u128::deserialise(&mut stream).unwrap(),
- 0xFF_0F_EF_1F_DF_2F_CF_3F_BF_4F_AF_5F_9F_6F_8F_7F,
- );
-
- assert_eq!(
- FixedString::<0x10>::deserialise(&mut stream).unwrap(),
- "m\u{00E1}na\u{00F0}ur",
- );
-
- assert_eq!(
- <[char; 0x5]>::deserialise(&mut stream).unwrap(),
- ['\u{03BB}', '\u{0391}', '\u{03BC}', '\u{0394}', '\u{03B1}'],
- );
-
- assert_eq!(
- Option::<()>::deserialise(&mut stream).unwrap(),
- Some(()),
- );
-
- assert_eq!(
- Option::<()>::deserialise(&mut stream).unwrap(),
- None,
- );
-
- assert_eq!(
- Result::<(), i8>::deserialise(&mut stream).unwrap(),
- Ok(()),
- );
-
- assert_eq!(
- Result::<(), i8>::deserialise(&mut stream).unwrap(),
- Err(i8::MIN),
- );
-}
diff --git a/src/dstream/mod.rs b/src/dstream/mod.rs
deleted file mode 100644
index ca7f619..0000000
--- a/src/dstream/mod.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-use crate::{Error, Result};
-
-use core::fmt::{Debug, Formatter};
-
-/// Byte stream for deserialisation.
-///
-/// This type borrows a byte slice (hence [`new`](Dstream::new)), keeping track internally of the used bytes.
-#[derive(Clone)]
-pub struct Dstream<'a> {
- data: &'a [u8],
- len: usize,
-}
-
-impl<'a> Dstream<'a> {
- /// Constructs a new byte stream.
- #[inline(always)]
- #[must_use]
- pub fn new<T: AsRef<[u8]> + ?Sized>(buf: &'a T) -> Self { Self {
- data: buf.as_ref(),
- len: buf.as_ref().len(),
- } }
-
- /// Takes bytes from the stream.
- ///
- /// # Errors
- ///
- /// If the internal buffer doesn't hold at least the requested amount of bytes, an [`EndOfStream`](Error::EndOfStream) error is returned.
- pub fn take(&mut self, req: usize) -> Result<&[u8]> {
- let rem = self.len;
-
- if rem < req { return Err(Error::EndOfStream { req, rem } ) }
-
- let start = self.data.len() - rem;
- let stop = start + req;
-
- self.len -= req;
- Ok(&self.data[start..stop])
- }
-
- /// Takes a single byte from the stream.
- ///
- /// # Errors
- ///
- /// If the internal buffer doesn't hold at least the requested amount of bytes, an [`EndOfStream`](Error::EndOfStream) error is returned.
- pub fn take_byte(&mut self) -> Result<u8> {
- const LEN: usize = 0x1;
-
- if self.len < LEN { return Err(Error::EndOfStream { req: LEN, rem: self.len } ) }
-
- self.len -= LEN;
-
- let index = self.data.len() - self.len;
- Ok(self.data[index])
- }
-}
-
-impl Debug for Dstream<'_> {
- fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
- self.data.fmt(f)
- }
-}
-
-impl<'a, T: AsRef<[u8]>> From<&'a T> for Dstream<'a> {
- fn from(value: &'a T) -> Self { Self::new(value) }
-}
diff --git a/src/error/mod.rs b/src/error/mod.rs
deleted file mode 100644
index 30e4c1e..0000000
--- a/src/error/mod.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-use core::error::Error as StdError;
-use core::fmt::{Display, Formatter};
-use core::str::Utf8Error;
-
-/// Mapping of [`core::result::Result`].
-pub type Result<T> = core::result::Result<T, Error>;
-
-/// Denotes an error.
-///
-/// These variants are used when deserialisation fails.
-/// Serialisations are assumed infallible.
-#[derive(Debug)]
-pub enum Error {
- /// An array could not hold the requested amount of elements.
- ArrayTooShort { req: usize, len: usize },
-
- /// A string encountered an invalid UTF-8 sequence.
- BadString { source: Utf8Error },
-
- /// Bytes were requested on an empty stream.
- EndOfStream { req: usize, rem: usize },
-
- /// A boolean encountered a value outside (0) and (1).
- InvalidBoolean { value: u8 },
-
- /// An invalid code point was encountered.
- ///
- /// This includes surrogate points in the inclusive range `U+D800` to `U+DFFF`, as well as values larger than `U+10FFFF`.
- InvalidCodePoint { value: u32 },
-
- /// An `isize` value couldn't fit into (16) bits.
- IsizeOutOfRange { value: isize },
-
- /// A non-zero integer encountered the value (0).
- NullInteger,
-
- /// A `usize` value couldn't fit into (16) bits.
- UsizeOutOfRange { value: usize },
-}
-
-impl Display for Error {
- fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
- use Error::*;
-
- match *self {
- ArrayTooShort { req, len } => {
- write!(f, "array of ({len}) element(s) cannot hold ({req})")
- },
-
- BadString { ref source } =>{
- write!(f, "unable to parse utf8: \"{source}\"")
- },
-
- EndOfStream { req, rem } => {
- write!(f, "({req}) byte(s) were requested but only ({rem}) byte(s) were left")
- },
-
- InvalidBoolean { value } => {
- write!(f, "expected boolean but got {value:#02X}")
- },
-
- InvalidCodePoint { value } => {
- write!(f, "code point U+{value:04X} is not valid")
- },
-
- IsizeOutOfRange { value } => {
- write!(f, "signed size value ({value}) cannot be serialised: must be in the range ({}) to ({})", i16::MIN, i16::MAX)
- },
-
- NullInteger => {
- write!(f, "expected non-zero integer but got (0)")
- },
-
- UsizeOutOfRange { value } => {
- write!(f, "unsigned size value ({value}) cannot be serialised: must be at most ({})", u16::MAX)
- },
- }
- }
-}
-
-impl StdError for Error {
- fn source(&self) -> Option<&(dyn StdError + 'static)> {
- use Error::*;
-
- match *self {
- BadString { ref source } => Some(source),
-
- _ => None,
- }
- }
-}
diff --git a/src/fixed_string/mod.rs b/src/fixed_string/mod.rs
deleted file mode 100644
index b0342d3..0000000
--- a/src/fixed_string/mod.rs
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-#[cfg(test)]
-mod test;
-
-use crate::{
- Deserialise,
- Dstream,
- Error,
- FixedStringIter,
- Serialise,
- Sstream,
-};
-
-use alloc::string::String;
-use core::cmp::Ordering;
-use core::fmt::{Debug, Display, Formatter};
-use core::ops::{Index, IndexMut};
-use core::str::FromStr;
-
-/// Owned string with maximum size.
-///
-/// This is in contrast to [String], which has no size limit is practice, and [str], which is unsized.
-#[derive(Clone)]
-pub struct FixedString<const N: usize> {
- buf: [char; N],
- len: usize,
-}
-
-impl<const N: usize> FixedString<N> {
- /// Constructs a new fixed string.
- ///
- /// The contents of the provided string are copied into the internal buffer.
- /// All residual characters are instanced as U+0000 `NULL`.
- ///
- /// # Errors
- ///
- /// If the given string `s` cannot fit into `N` characters, an [`ArrayTooShort`](Error::ArrayTooShort) error is returned.
- pub fn new(s: &str) -> Result<Self, Error> {
- let mut buf = ['\0'; N];
- let len = s.chars().count();
-
- for (i, c) in s.chars().enumerate() {
- if i >= N { return Err(Error::ArrayTooShort { req: len, len: N }) }
-
- buf[i] = c;
- }
-
- Ok(Self { buf, len })
- }
-
- /// Returns the length of the string.
- ///
- /// This does not necessarily equal the value of `N`, as the internal buffer is not required to be used fully.
- #[inline(always)]
- #[must_use]
- pub const fn len(&self) -> usize { self.len }
-
- /// Checks if the string is empty, i.e. `self.len() == 0x0`.
- #[inline(always)]
- #[must_use]
- pub const fn is_empty(&self) -> bool { self.len == 0x0 }
-
- /// Borrows the character at the specified index.
- ///
- /// If no element exists at that position, [`None`] is returned instead.
- #[inline]
- #[must_use]
- pub const fn get(&self, index: usize) -> Option<&char> {
- if index >= self.len {
- None
- } else {
- Some(&self.buf[index])
- }
- }
-
- /// Mutably borrows the character at the specified index.
- ///
- /// If no element exists at that position, [`None`] is returned instead.
- #[inline]
- #[must_use]
- pub fn get_mut(&mut self, index: usize) -> Option<&mut char> {
- if index >= self.len {
- None
- } else {
- Some(&mut self.buf[index])
- }
- }
-
- /// Returns an iterator to the contained characters.
- #[inline(always)]
- pub fn iter(&self) -> core::slice::Iter<'_, char> { self.buf[0x0..self.len].iter() }
-
- /// Returns a mutable iterator to the contained characters.
- #[inline(always)]
- pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, char> { self.buf[0x0..self.len].iter_mut() }
-}
-
-impl<const N: usize> Debug for FixedString<N> {
- fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
- write!(f, "\"")?;
- for c in self { write!(f, "{}", c.escape_debug())? }
- write!(f, "\"")?;
-
- Ok(())
- }
-}
-
-impl<const N: usize> Deserialise for FixedString<N> {
- type Error = Error;
-
- fn deserialise(stream: &mut Dstream) -> Result<Self, Self::Error> {
- let len = usize::deserialise(stream)?;
- let data = stream.take(len)?;
-
- let s = core::str::from_utf8(data)
- .map_err(|e| Error::BadString { source: e })?;
-
- let len = s.chars().count();
-
- if len > N {
- return Err(Error::ArrayTooShort { req: len, len: N });
- }
-
- let mut buf = ['\0'; N];
- for (i, c) in s.chars().enumerate() {
- buf[i] = c;
- }
-
- Ok(Self { buf, len })
- }
-}
-
-impl<const N: usize> Default for FixedString<N> {
- #[inline(always)]
- fn default() -> Self { Self {
- buf: ['\0'; N],
- len: 0x0,
- } }
-}
-
-impl<const N: usize> Display for FixedString<N> {
- fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
- for c in self { write!(f, "{c}")? }
-
- Ok(())
- }
-}
-
-impl<const N: usize> Eq for FixedString<N> { }
-
-impl<const N: usize> From<[char; N]> for FixedString<N> {
- fn from(value: [char; N]) -> Self { Self {
- buf: value,
- len: N,
- } }
-}
-
-impl<const N: usize> FromStr for FixedString<N> {
- type Err = Error;
-
- fn from_str(s: &str) -> Result<Self, Error> { Self::new(s) }
-}
-
-impl<const N: usize> Index<usize> for FixedString<N> {
- type Output = char;
-
- fn index(&self, index: usize) -> &Self::Output { self.get(index).unwrap() }
-}
-
-impl<const N: usize> IndexMut<usize> for FixedString<N> {
- fn index_mut(&mut self, index: usize) -> &mut Self::Output { self.get_mut(index).unwrap() }
-}
-
-impl<const N: usize> IntoIterator for FixedString<N> {
- type Item = char;
-
- type IntoIter = FixedStringIter<N>;
-
- fn into_iter(self) -> Self::IntoIter {
- FixedStringIter {
- buf: self.buf,
- len: self.len,
-
- pos: Some(0x0),
- }
- }
-}
-
-impl<'a, const N: usize> IntoIterator for &'a FixedString<N> {
- type Item = &'a char;
-
- type IntoIter = core::slice::Iter<'a, char>;
-
- fn into_iter(self) -> Self::IntoIter { self.iter() }
-}
-
-impl<'a, const N: usize> IntoIterator for &'a mut FixedString<N> {
- type Item = &'a mut char;
-
- type IntoIter = core::slice::IterMut<'a, char>;
-
- fn into_iter(self) -> Self::IntoIter { self.iter_mut() }
-}
-
-impl<const N: usize> Ord for FixedString<N> {
- fn cmp(&self, other: &Self) -> Ordering { self.partial_cmp(other).unwrap() }
-}
-
-impl<const N: usize, const M: usize> PartialEq<FixedString<M>> for FixedString<N> {
- fn eq(&self, other: &FixedString<M>) -> bool {
- if self.len() != other.len() { return false };
-
- for i in 0x0..self.len() {
- if self.buf[i] != other.buf[i] { return false };
- }
-
- true
- }
-}
-
-impl<const N: usize> PartialEq<&str> for FixedString<N> {
- fn eq(&self, other: &&str) -> bool {
- for (i, c) in other.chars().enumerate() {
- if self.buf.get(i) != Some(&c) { return false };
- }
-
- true
- }
-}
-
-impl<const N: usize, const M: usize> PartialOrd<FixedString<M>> for FixedString<N> {
- fn partial_cmp(&self, other: &FixedString<M>) -> Option<Ordering> {
- let len = self.len().max(other.len());
-
- for i in 0x0..len {
- let lc = self.get(i);
- let rc = other.get(i);
-
- match (lc, rc) {
- (None, None) => return Some(Ordering::Equal),
- (Some(_), None) => return Some(Ordering::Greater),
- (None, Some(_)) => return Some(Ordering::Less),
-
- (Some(lc), Some(rc)) => {
- let ordering = lc.cmp(rc);
-
- if ordering != Ordering::Equal { return Some(ordering) };
- }
- }
- }
-
- Some(Ordering::Equal)
- }
-}
-
-impl<const N: usize> Serialise for FixedString<N> {
- type Error = Error;
-
- const SERIALISE_LIMIT: usize = N * 0x4;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- let s: String = self.iter().collect();
-
- count += s.len().serialise(stream)?;
- count += stream.add(&s.into_bytes())?;
-
- Ok(count)
- }
-}
-
-impl<const N: usize> TryFrom<&str> for FixedString<N> {
- type Error = Error;
-
- #[inline(always)]
- fn try_from(value: &str) -> Result<Self, Self::Error> { Self::new(value) }
-}
diff --git a/src/fixed_string/test.rs b/src/fixed_string/test.rs
deleted file mode 100644
index 1599efc..0000000
--- a/src/fixed_string/test.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-use crate::FixedString;
-
-use core::cmp::Ordering;
-
-#[test]
-fn test_fixed_string() {
- let str0 = FixedString::<0xC>::new("Hello there!").unwrap();
- let str1 = FixedString::<0xE>::new("MEIN_GRO\u{1E9E}_GOTT").unwrap();
- let str2 = FixedString::<0x5>::new("Hello").unwrap();
-
- assert_eq!(str0.partial_cmp(&str0), Some(Ordering::Equal));
- assert_eq!(str0.partial_cmp(&str1), Some(Ordering::Less));
- assert_eq!(str0.partial_cmp(&str2), Some(Ordering::Greater));
-
- assert_eq!(str1.partial_cmp(&str0), Some(Ordering::Greater));
- assert_eq!(str1.partial_cmp(&str1), Some(Ordering::Equal));
- assert_eq!(str1.partial_cmp(&str2), Some(Ordering::Greater));
-
- assert_eq!(str2.partial_cmp(&str0), Some(Ordering::Less));
- assert_eq!(str2.partial_cmp(&str1), Some(Ordering::Less));
- assert_eq!(str2.partial_cmp(&str2), Some(Ordering::Equal));
-}
diff --git a/src/fixed_string_iter/mod.rs b/src/fixed_string_iter/mod.rs
deleted file mode 100644
index 088f61f..0000000
--- a/src/fixed_string_iter/mod.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-/// Iterator to a fixed string.
-pub struct FixedStringIter<const N: usize> {
- pub(in crate) buf: [char; N],
- pub(in crate) len: usize,
-
- pub(in crate) pos: Option<usize>,
-}
-
-impl<const N: usize> Iterator for FixedStringIter<N> {
- type Item = char;
-
- fn next(&mut self) -> Option<Self::Item> {
- let pos = self.pos.as_mut()?;
-
- if *pos >= self.len { return None };
-
- let item = self.buf[*pos];
- *pos += 0x1;
-
- Some(item)
- }
-}
diff --git a/src/lib.rs b/src/lib.rs
deleted file mode 100644
index 4355f75..0000000
--- a/src/lib.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-#![doc(html_logo_url = "https://gitlab.com/bjoernager/bzipper/-/raw/master/doc-icon.svg?ref_type=heads")]
-
-//! Binary (de)serialisation.
-//!
-//! Contrary to [Serde](https://crates.io/crates/serde/)/[Bincode](https://crates.io/crates/bincode/), the goal of `bzipper` is to serialise with a known size constraint.
-//! Therefore, this crate may be more suited for networking or other cases where a fixed-sized buffer is needed.
-//!
-//! Keep in mind that this project is still work-in-progress.
-//!
-//! This crate does not require any dependencies at the moment.
-//! It is also compatible with `no_std`.
-//!
-//! # Data model
-//!
-//! Most primitive types serialise losslessly, with the exception being [`usize`] and [`isize`].
-//! These serialise as [`u16`] and [`i16`], respectively, for portability reasons.
-//!
-//! Unsized types, such as [`str`] and [slices](slice), are not supported.
-//! Instead, [arrays](array) should be used.
-//! For strings, the [`FixedString`] type is also provided.
-//!
-//! # Usage
-//!
-//! This crate revolves around the [`Serialise`] and [`Deserialise`] traits, both of which work around streams (more specifically, [d-streams](Dstream) and [s-streams](Sstream)).
-//!
-//! Many core types come implemented with `bzipper`, including primitives as well as some standard library types such as [`Option`] and [`Result`](core::result::Result).
-//!
-//! ## Serialisation
-//!
-//! To serialise an object implementing `Serialise`, simply allocate a so-called "s-stream" (short for *serialisation stream*) with the [`Sstream`] type:
-//!
-//! ```
-//! let mut buf: [u8; 16] = Default::default();
-//!
-//! let mut stream = bzipper::Sstream::new(&mut buf);
-//! ```
-//!
-//! The resulting stream is immutable in the sense that it cannot grow its buffer, altough it does keep track of the buffer's state.
-//!
-//! A byte sequence can be added to our new stream by passing the stream to a call to the [`serialise`](Serialise::serialise) method:
-//!
-//! ```
-//! use bzipper::Serialise;
-//!
-//! let mut buf: [u8; 2] = Default::default();
-//! let mut stream = bzipper::Sstream::new(&mut buf);
-//!
-//! 0x4554_u16.serialise(&mut stream).unwrap();
-//! ```
-//!
-//! The ammount of bytes used by the serialiser (that is, the ammount of bytes written to the stream) is indicated by its return value (i.e. it has the type `Result<usize, Serialise::Error>`).
-//!
-//! Whilst the *maximum* ammount of bytes is specified by the [`SERIALISE_LIMIT`](Serialise::SERIALISE_LIMIT) constant, this can in cases be lower (for example with [`None`] variants which are always encoded as a single, null byte).
-//!
-//! When serialising primitives, the resulting byte stream is in big endian (a.k.a. network endian).
-//! It is recommended for implementors to adhere to this convention as well.
-//!
-//! After serialisation, the s-stream records the new write-to position of the buffer. This allows for *chaining* of serialisations, which can prove useful when implementing the trait for custom types.
-//!
-//! ## Deserialisation
-//!
-//! As with serialisation, deserialisation uses streams (just with the [`Dstream`] type; short for *deserialisation stream*):
-//!
-//! ```
-//! let data = [0x45, 0x54];
-//!
-//! let mut stream = bzipper::Dstream::new(&data);
-//! ```
-//!
-//! Using these streams is also just as simple as with s-streams:
-//!
-//! ```
-//! use bzipper::Deserialise;
-//!
-//! let data = [0x45, 0x54];
-//! let mut stream = bzipper::Dstream::new(&data);
-//!
-//! assert_eq!(u16::deserialise(&mut stream).unwrap(), 0x4554);
-//! ```
-//!
-//! When chaining serialisations, keep in mind that appropriate deserialisations should come in **reverse order** (streams function similarly to stacks in this sense).
-
-#![no_std]
-
-extern crate alloc;
-
-macro_rules! use_mod {
- ($vis:vis $name:ident) => {
- mod $name;
- $vis use $name::*;
- };
-}
-pub(in crate) use use_mod;
-
-use_mod!(pub buffer);
-use_mod!(pub deserialise);
-use_mod!(pub dstream);
-use_mod!(pub error);
-use_mod!(pub fixed_string);
-use_mod!(pub fixed_string_iter);
-use_mod!(pub serialise);
-use_mod!(pub sstream);
diff --git a/src/serialise/mod.rs b/src/serialise/mod.rs
deleted file mode 100644
index 16c8313..0000000
--- a/src/serialise/mod.rs
+++ /dev/null
@@ -1,676 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-#[cfg(test)]
-mod test;
-
-use crate::{Error, Sstream};
-
-use alloc::boxed::Box;
-use core::convert::Infallible;
-use core::error::Error as StdError;
-use core::mem::size_of;
-use core::num::NonZero;
-
-/// Types capable of being serialised.
-pub trait Serialise: Sized {
- /// The error of serialisation.
- ///
- /// Use [`Infallible`] if **all** deserialisations are infallible, as is the case of zero-length types (such as [the unit type](unit)).
- type Error;
-
- /// The maximum amount of bytes that can result from serialisation.
- ///
- /// Until derive macros are implemented, this value should be set to the sum of the members' own size limits (if chaining is used, that is):
- ///
- /// ```
- /// use bzipper::{Serialise, Sstream};
- ///
- /// struct Foo {
- /// bar: u16,
- /// baz: f32,
- /// }
- ///
- /// impl Serialise for Foo {
- /// type Error = bzipper::Error;
- ///
- /// const SERIALISE_LIMIT: usize = u16::SERIALISE_LIMIT + f32::SERIALISE_LIMIT;
- ///
- /// fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- /// let mut count = 0x0;
- ///
- /// // Serialise fields using chaining.
- /// count += self.bar.serialise(stream)?;
- /// count += self.baz.serialise(stream)?;
- ///
- /// Ok(count)
- /// }
- /// }
- /// ```
- ///
- /// In the future, dervice macros will make manual chaining redundant.
- const SERIALISE_LIMIT: usize;
-
- /// Serialises `self` into a byte stream.
- ///
- /// The number of bytes written is returned.
- /// This should **not** exceed [`SERIALISE_LIMIT`](Serialise::SERIALISE_LIMIT), and doing so is considered a logic error.
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error>;
-}
-
-macro_rules! impl_float {
- ($type:ty) => {
- impl Serialise for $type {
- type Error = Error;
-
- const SERIALISE_LIMIT: usize = size_of::<$type>();
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let data = self.to_be_bytes();
- stream.add(&data)?;
-
- Ok(data.len())
- }
- }
- };
-}
-
-macro_rules! impl_int {
- ($type:ty) => {
- impl Serialise for $type {
- type Error = Error;
-
- const SERIALISE_LIMIT: usize = size_of::<$type>();
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let data = self.to_be_bytes();
- stream.add(&data)?;
-
- Ok(data.len())
- }
- }
- };
-}
-
-macro_rules! impl_non_zero {
- ($type:ty) => {
- impl Serialise for NonZero<$type> {
- type Error = <$type as Serialise>::Error;
-
- const SERIALISE_LIMIT: usize = size_of::<$type>();
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- self.get().serialise(stream)
- }
- }
- };
-}
-
-impl<T0, T1> Serialise for (T0, T1)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2> Serialise for (T0, T1, T2)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3> Serialise for (T0, T1, T2, T3)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3, T4> Serialise for (T0, T1, T2, T3, T4)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>,
- T4: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT
- + T4::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
- count += self.4.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5> Serialise for (T0, T1, T2, T3, T4, T5)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>,
- T4: Serialise<Error: StdError + 'static>,
- T5: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT
- + T4::SERIALISE_LIMIT
- + T5::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
- count += self.4.serialise(stream)?;
- count += self.5.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6> Serialise for (T0, T1, T2, T3, T4, T5, T6)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>,
- T4: Serialise<Error: StdError + 'static>,
- T5: Serialise<Error: StdError + 'static>,
- T6: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT
- + T4::SERIALISE_LIMIT
- + T5::SERIALISE_LIMIT
- + T6::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
- count += self.4.serialise(stream)?;
- count += self.5.serialise(stream)?;
- count += self.6.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7> Serialise for (T0, T1, T2, T3, T4, T5, T6, T7)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>,
- T4: Serialise<Error: StdError + 'static>,
- T5: Serialise<Error: StdError + 'static>,
- T6: Serialise<Error: StdError + 'static>,
- T7: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT
- + T4::SERIALISE_LIMIT
- + T5::SERIALISE_LIMIT
- + T6::SERIALISE_LIMIT
- + T7::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
- count += self.4.serialise(stream)?;
- count += self.5.serialise(stream)?;
- count += self.6.serialise(stream)?;
- count += self.7.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> Serialise for (T0, T1, T2, T3, T4, T5, T6, T7, T8)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>,
- T4: Serialise<Error: StdError + 'static>,
- T5: Serialise<Error: StdError + 'static>,
- T6: Serialise<Error: StdError + 'static>,
- T7: Serialise<Error: StdError + 'static>,
- T8: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT
- + T4::SERIALISE_LIMIT
- + T5::SERIALISE_LIMIT
- + T6::SERIALISE_LIMIT
- + T7::SERIALISE_LIMIT
- + T8::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
- count += self.4.serialise(stream)?;
- count += self.5.serialise(stream)?;
- count += self.6.serialise(stream)?;
- count += self.7.serialise(stream)?;
- count += self.8.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> Serialise for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>,
- T4: Serialise<Error: StdError + 'static>,
- T5: Serialise<Error: StdError + 'static>,
- T6: Serialise<Error: StdError + 'static>,
- T7: Serialise<Error: StdError + 'static>,
- T8: Serialise<Error: StdError + 'static>,
- T9: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT
- + T4::SERIALISE_LIMIT
- + T5::SERIALISE_LIMIT
- + T6::SERIALISE_LIMIT
- + T7::SERIALISE_LIMIT
- + T8::SERIALISE_LIMIT
- + T9::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
- count += self.4.serialise(stream)?;
- count += self.5.serialise(stream)?;
- count += self.6.serialise(stream)?;
- count += self.7.serialise(stream)?;
- count += self.8.serialise(stream)?;
- count += self.9.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Serialise for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>,
- T4: Serialise<Error: StdError + 'static>,
- T5: Serialise<Error: StdError + 'static>,
- T6: Serialise<Error: StdError + 'static>,
- T7: Serialise<Error: StdError + 'static>,
- T8: Serialise<Error: StdError + 'static>,
- T9: Serialise<Error: StdError + 'static>,
- T10: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT
- + T4::SERIALISE_LIMIT
- + T5::SERIALISE_LIMIT
- + T6::SERIALISE_LIMIT
- + T7::SERIALISE_LIMIT
- + T8::SERIALISE_LIMIT
- + T9::SERIALISE_LIMIT
- + T10::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
- count += self.4.serialise(stream)?;
- count += self.5.serialise(stream)?;
- count += self.6.serialise(stream)?;
- count += self.7.serialise(stream)?;
- count += self.8.serialise(stream)?;
- count += self.9.serialise(stream)?;
- count += self.10.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Serialise for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
-where
- T0: Serialise<Error: StdError + 'static>,
- T1: Serialise<Error: StdError + 'static>,
- T2: Serialise<Error: StdError + 'static>,
- T3: Serialise<Error: StdError + 'static>,
- T4: Serialise<Error: StdError + 'static>,
- T5: Serialise<Error: StdError + 'static>,
- T6: Serialise<Error: StdError + 'static>,
- T7: Serialise<Error: StdError + 'static>,
- T8: Serialise<Error: StdError + 'static>,
- T9: Serialise<Error: StdError + 'static>,
- T10: Serialise<Error: StdError + 'static>,
- T11: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize =
- T0::SERIALISE_LIMIT
- + T1::SERIALISE_LIMIT
- + T2::SERIALISE_LIMIT
- + T3::SERIALISE_LIMIT
- + T4::SERIALISE_LIMIT
- + T5::SERIALISE_LIMIT
- + T6::SERIALISE_LIMIT
- + T7::SERIALISE_LIMIT
- + T8::SERIALISE_LIMIT
- + T9::SERIALISE_LIMIT
- + T10::SERIALISE_LIMIT
- + T11::SERIALISE_LIMIT;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- count += self.0.serialise(stream)?;
- count += self.1.serialise(stream)?;
- count += self.2.serialise(stream)?;
- count += self.3.serialise(stream)?;
- count += self.4.serialise(stream)?;
- count += self.5.serialise(stream)?;
- count += self.6.serialise(stream)?;
- count += self.7.serialise(stream)?;
- count += self.8.serialise(stream)?;
- count += self.9.serialise(stream)?;
- count += self.10.serialise(stream)?;
- count += self.11.serialise(stream)?;
-
- Ok(count)
- }
-}
-
-impl<T: Serialise<Error: StdError + 'static>, const N: usize> Serialise for [T; N] {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize = T::SERIALISE_LIMIT * N;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- self.len().serialise(stream)?;
- for v in self { count += v.serialise(stream)? }
-
- Ok(count)
- }
-}
-
-impl Serialise for () {
- type Error = Infallible;
-
- const SERIALISE_LIMIT: usize = size_of::<Self>();
-
- #[inline(always)]
- fn serialise(&self, mut _stream: &mut Sstream) -> Result<usize, Self::Error> {
- Ok(Self::SERIALISE_LIMIT)
- }
-}
-
-impl Serialise for bool {
- type Error = Error;
-
- const SERIALISE_LIMIT: usize = size_of::<Self>();
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- u8::from(*self).serialise(stream)
- }
-}
-
-impl Serialise for char {
- type Error = Error;
-
- const SERIALISE_LIMIT: usize = size_of::<Self>();
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- u32::from(*self).serialise(stream)
- }
-}
-
-// Especially useful for `Result<T, Infallible>`.
-impl Serialise for Infallible {
- type Error = Self;
-
- const SERIALISE_LIMIT: usize = size_of::<Self>();
-
- fn serialise(&self, mut _stream: &mut Sstream) -> Result<usize, Self::Error> { unreachable!() }
-}
-
-impl Serialise for isize {
- type Error = Error;
-
- const SERIALISE_LIMIT: usize = size_of::<i16>();
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let value = i16::try_from(*self)
- .map_err(|_| Error::IsizeOutOfRange { value: *self })?;
-
- value.serialise(stream)
- }
-}
-
-impl<T: Serialise<Error: StdError + 'static>> Serialise for Option<T> {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize = T::SERIALISE_LIMIT + 0x1;
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let mut count = 0x0;
-
- match *self {
- None => {
- count += false.serialise(stream)?;
- // No need to zero-fill.
- },
-
- Some(ref v) => {
- count += true.serialise(stream)?;
- count += v.serialise(stream)?;
- },
- };
-
- Ok(count)
- }
-}
-
-impl<T, E> Serialise for core::result::Result<T, E>
-where
- T: Serialise<Error: StdError + 'static>,
- E: Serialise<Error: StdError + 'static>, {
- type Error = Box<dyn StdError>;
-
- const SERIALISE_LIMIT: usize = const {
- if size_of::<T>() > size_of::<T>() {
- size_of::<T>()
- } else {
- size_of::<E>()
- }
- };
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- // Remember the descriminant.
- let mut count = 0x0;
-
- match *self {
- Ok(ref v) => {
- count += false.serialise(stream)?;
- count += v.serialise(stream)?;
- },
-
- Err(ref e) => {
- count += true.serialise(stream)?;
- count += e.serialise(stream)?;
- },
- };
-
- Ok(count)
- }
-}
-
-impl Serialise for usize {
- type Error = Error;
-
- const SERIALISE_LIMIT: Self = size_of::<u16>();
-
- fn serialise(&self, stream: &mut Sstream) -> Result<usize, Self::Error> {
- let value = u16::try_from(*self)
- .map_err(|_| Error::UsizeOutOfRange { value: *self })?;
-
- value.serialise(stream)
- }
-}
-
-impl_float!(f32);
-impl_float!(f64);
-
-impl_int!(i128);
-impl_int!(i16);
-impl_int!(i32);
-impl_int!(i64);
-impl_int!(i8);
-impl_int!(u128);
-impl_int!(u16);
-impl_int!(u32);
-impl_int!(u64);
-impl_int!(u8);
-
-impl_non_zero!(i128);
-impl_non_zero!(i16);
-impl_non_zero!(i32);
-impl_non_zero!(i64);
-impl_non_zero!(i8);
-impl_non_zero!(isize);
-impl_non_zero!(u128);
-impl_non_zero!(u16);
-impl_non_zero!(u32);
-impl_non_zero!(u64);
-impl_non_zero!(u8);
-impl_non_zero!(usize);
diff --git a/src/serialise/test.rs b/src/serialise/test.rs
deleted file mode 100644
index 43f2b9f..0000000
--- a/src/serialise/test.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-use crate::{FixedString, Serialise, Sstream};
-
-use alloc::boxed::Box;
-use alloc::vec;
-
-#[test]
-fn test_serialise() {
- let mut buf = vec![0x00; 0x50];
- let mut stream = Sstream::new(&mut buf);
-
- 0x00_u8.serialise(&mut stream).unwrap();
- 0xFF_u8.serialise(&mut stream).unwrap();
- 0x7F_u8.serialise(&mut stream).unwrap();
-
- 0x0F_7E_u16.serialise(&mut stream).unwrap();
-
- 0x00_2F_87_E7_u32.serialise(&mut stream).unwrap();
-
- 0xF3_37_CF_8B_DB_03_2B_39_u64.serialise(&mut stream).unwrap();
-
- 0x45_A0_15_6A_36_77_17_8A_83_2E_3C_2C_84_10_58_1A_u128.serialise(&mut stream).unwrap();
-
- FixedString::<0x1>::new("A").unwrap().serialise(&mut stream).unwrap();
- FixedString::<0x8>::new("l\u{00F8}gma\u{00F0}ur").unwrap().serialise(&mut stream).unwrap();
-
- ['\u{03B4}', '\u{0190}', '\u{03BB}', '\u{03A4}', '\u{03B1}'].serialise(&mut stream).unwrap();
-
- Ok::<u16, char>(0x45_45).serialise(&mut stream).unwrap();
- Err::<u16, char>(char::REPLACEMENT_CHARACTER).serialise(&mut stream).unwrap();
-
- None::<()>.serialise(&mut stream).unwrap();
- Some::<()>(()).serialise(&mut stream).unwrap();
-
- let data: Box<[u8]> = buf.into();
-
- assert_eq!(
- data.as_ref(),
- [
- 0x00, 0xFF, 0x7F, 0x0F, 0x7E, 0x00, 0x2F, 0x87,
- 0xE7, 0xF3, 0x37, 0xCF, 0x8B, 0xDB, 0x03, 0x2B,
- 0x39, 0x45, 0xA0, 0x15, 0x6A, 0x36, 0x77, 0x17,
- 0x8A, 0x83, 0x2E, 0x3C, 0x2C, 0x84, 0x10, 0x58,
- 0x1A, 0x00, 0x01, 0x41, 0x00, 0x0A, 0x6C, 0xC3,
- 0xB8, 0x67, 0x6D, 0x61, 0xC3, 0xB0, 0x75, 0x72,
- 0x00, 0x05, 0x00, 0x00, 0x03, 0xB4, 0x00, 0x00,
- 0x01, 0x90, 0x00, 0x00, 0x03, 0xBB, 0x00, 0x00,
- 0x03, 0xA4, 0x00, 0x00, 0x03, 0xB1, 0x00, 0x45,
- 0x45, 0x01, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x01,
- ],
- );
-} \ No newline at end of file
diff --git a/src/sstream/mod.rs b/src/sstream/mod.rs
deleted file mode 100644
index 83536d0..0000000
--- a/src/sstream/mod.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2024 Gabriel Bjørnager Jensen.
-//
-// This file is part of bzipper.
-//
-// bzipper is free software: you can redistribute
-// it and/or modify it under the terms of the GNU
-// Lesser General Public License as published by
-// the Free Software Foundation, either version 3
-// of the License, or (at your option) any later
-// version.
-//
-// bzipper is distributed in the hope that it will
-// be useful, but WITHOUT ANY WARRANTY; without
-// even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Less-
-// er General Public License along with bzipper. If
-// not, see <https://www.gnu.org/licenses/>.
-
-use crate::{Error, Result};
-
-use core::fmt::{Debug, Formatter};
-
-/// Byte stream for serialisation.
-///
-/// This type borrows a byte slice (hence [`new`](Sstream::new)), keeping track internally of the used bytes.
-#[derive(Eq, PartialEq)]
-pub struct Sstream<'a> {
- data: &'a mut [u8],
- len: usize
-}
-
-impl<'a> Sstream<'a> {
- /// Constructs a new byte stream.
- ///
- /// If the borrowed slice already contains data, this may overwritten by subsequent serialisations.
- #[inline(always)]
- #[must_use]
- pub fn new(data: &'a mut [u8]) -> Self { Self { data, len: 0x0 } }
-
- /// Extends the byte stream.
- ///
- /// # Errors
- ///
- /// If the stream cannot hold the requested bytes, an [`EndOfStream`](Error::EndOfStream) instance is returned.
- pub fn add(&mut self, extra: &[u8]) -> Result<usize> {
- let rem = self.data.len() - self.len;
- let req = extra.len();
-
- if rem.checked_sub(req).is_none() {
- return Err(Error::EndOfStream { req, rem });
- }
-
- let start = self.len;
- let stop = self.len + req;
-
- self.len += req;
- self.data[start..stop].copy_from_slice(extra);
-
- Ok(req)
- }
-
- /// Extends the byte stream by a single byte.
- ///
- /// # Errors
- ///
- /// If the stream cannot hold the byte, an [`EndOfStream`](Error::EndOfStream) instance is returned.
- pub fn add_byte(&mut self, extra: u8) -> Result<usize> {
- self.add(&[extra])
- }
-
- /// Yields the length of the stream.
- ///
- /// That is, the amount of bytes written so far.
- #[inline(always)]
- #[must_use]
- pub const fn len(&self) -> usize { self.len }
-
- /// Tests if the stream is empty.
- #[inline(always)]
- #[must_use]
- pub const fn is_empty(&self) -> bool { self.len == 0x0 }
-
- /// Returns a slice to the stream contents.
- ///
- /// This includes all previously written bytes.
- #[inline(always)]
- #[must_use]
- pub fn as_slice(&self) -> &[u8] { &self.data[0x0..self.len] }
-}
-
-impl AsRef<[u8]> for Sstream<'_> {
- #[inline(always)]
- fn as_ref(&self) -> &[u8] { self.as_slice() }
-}
-
-impl Debug for Sstream<'_> {
- fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
- self.data.fmt(f)
- }
-}