oct 0.37.1

Octonary utilities.
Documentation
// Copyright 2024-2026 Gabriel Bjørnager Jensen.
//
// SPDX: MIT OR Apache-2.0

//! Serialisation/deserialisation facilities.
//!
//! This module provides portable serialisation and
//! deserialisation algorithms, e.g. for network
//! communications.
//!
//! # Scheme
//!
//! Oct itself does not specify any stable encoding
//! scheme, although there are made some guarantees
//! as to how some types are serialised.
//!
//! The following types are compatible, i.e. are
//! guaranteed to serialise with the same scheme:
//!
//! * `T`, `Arc<T>`, `[T; 1]`, `Atomic<T>`,
//!   `Box<T>`, `Cell<T>`, `Cow<'_, T>`,
//!   `LazyCell<T>`, `LazyLock<T>`,
//!   `ManuallyDrop<T>`, `Mutex<T>`, `NonZero<T>`,
//!   `&T`, `&mut T`, `Reverse<T>`, `Rc<T>`,
//!   `cell::Ref<'_, T>`, `RefCell<T>`,
//!   `cell::RefMut<'_, T>`, `RwLock<T>`,
//!   `Saturating<T>`, `(T, )`, `UnsafeCell<T>`,
//!   `Wrapping<T>`
//! * `[T; N]`, `Simd<T, N>`
//! * `[T; 2]`, `(T, T)`
//! * `[T; 3]`, `(T, T, T)`
//! * `[T; 4]`, `(T, T, T, T)`
//! * `[T; 5]`, `(T, T, T, T, T)`
//! * `[T; 6]`, `(T, T, T, T, T, T)`
//! * `[T; 7]`, `(T, T, T, T, T, T, T)`
//! * `[T; 8]`, `(T, T, T, T, T, T, T, T)`
//! * `[T; 9]`, `(T, T, T, T, T, T, T, T, T)`
//! * `[T; 10]`,
//!   `(T, T, T, T, T, T, T, T, T, T)`
//! * `[T; 11]`,
//!   `(T, T, T, T, T, T, T, T, T, T, T)`
//! * `[T; 12]`,
//!   `(T, T, T, T, T, T, T, T, T, T, T, T)`
//! * `[T]`, `LinkedList<T>`, `Vec<T>`,
//!   `VecDeque<T>`
//! * `Option<T>`, `OnceCell<T>`, `OnceLock<T>`,
//!   `rc::Weak<T>`, `sync::Weak<T>`
//! * `u8`, `i8`, `bool`, `ascii::Char`
//! * `u16`, `i16`, `f16`
//! * `u32`, `i32`, `f32`, `char`,
//!   `Ipv4Addr`
//! * `u64`, `i64`, `f64`
//! * `u64`, `i64`, `f64`
//! * `u128`, `i128`, `f128`, `Ipv6Addr`
//! * `[u8]`, `ByteStr`, `str`
//! * `Vec<u8>`, `ByteString`, `String`
//!
//! Whether or not these serialisations can be
//! punned depends on the serialised value and the
//! deserialising type (e.g. `2_u8` deserialised as
//! `bool` is rejected.) Ty ty ty!
//!
//! Furthermore, all values of a given
//! type can be assumed to be "serialisable," at
//! least as long as the values in question are
//! portable. The following type test for these
//! values when serialising:
//!
//! * [`usize`] and [`isize`] serialise as [`u16`]
//!   and [`i16`], respectively; thus, only values
//!   in the respective ranges `0..=65535` and
//!   `-32768..=32767` are accepted.
//!
#![cfg_attr(feature = "alloc",      doc = "[`VecDeque`]: alloc::collections::VecDeque")]
#![cfg_attr(not(feature = "alloc"), doc = "[`VecDeque`]: <https://doc.rust-lang.org/nightly/alloc/collections/struct.VecDeque.html>")]
//!
//! # Examples
//!
#![cfg_attr(feature = "proc_macro", doc = include_str!("serdes_derive_examples.md"))]

#![doc(alias = "serde")]

#![cfg(feature = "serdes")]

mod deserialise;
mod max_serialised_size;
mod serialise;
mod util;
mod slot;

pub use deserialise::Deserialise;
pub use max_serialised_size::MaxSerialisedSize;
pub use serialise::Serialise;
pub use util::serialise_iter;

#[cfg(feature = "alloc")]
pub use slot::Slot;

/// Implements [`Deserialise`] for the given type.
///
/// [`Deserialise`]: trait@Deserialise
#[cfg(feature = "proc_macro")]
#[doc(inline)]
pub use oct_macros::Deserialise;

/// Implements [`MaxSerialisedSize`] for the given type.
///
/// [`MaxSerialisedSize`]: trait@MaxSerialisedSize
#[cfg(feature = "proc_macro")]
#[doc(inline)]
pub use oct_macros::MaxSerialisedSize;

/// Implements [`Serialise`] for the given type.
///
/// [`Serialise`]: trait@Serialise
#[cfg(feature = "proc_macro")]
#[doc(inline)]
pub use oct_macros::Serialise;

/// Serialisation/deserialisation constants.
mod consts {
	/// The discriminant value for [`Bound::Included`].
	///
	/// [`Bound::Included`]: core::ops::Bound::Included
	pub(super) const BOUND_INCLUDED: u8 = 0;

	/// The discriminant value for [`Bound::Excluded`].
	///
	/// [`Bound::Excluded`]: core::ops::Bound::Excluded
	pub(super) const BOUND_EXCLUDED: u8 = 1;

	/// The discriminant value for [`Bound::Unbounded`].
	///
	/// [`Bound::Unbounded`]: core::ops::Bound::Unbounded
	pub(super) const BOUND_UNBOUNDED: u8 = 2;

	/// The discriminant value for
	/// [`atomic::Ordering::AcqRel`].
	///
	/// [`atomic::Ordering::AcqRel`]: core::sync::atomic::Ordering::AcqRel
	pub(super) const ATOMIC_ORDERING_ACQ_REL: u8 = 3;

	/// The discriminant value for
	/// [`atomic::Ordering::Acquire`].
	///
	/// [`atomic::Ordering::Acquire`]: core::sync::atomic::Ordering::Acquire
	pub(super) const ATOMIC_ORDERING_ACQUIRE: u8 = 2;

	/// The discriminant value for
	/// [`atomic::Ordering::Relaxed`].
	///
	/// [`atomic::Ordering::Relaxed`]: core::sync::atomic::Ordering::Relaxed
	pub(super) const ATOMIC_ORDERING_RELAXED: u8 = 0;

	/// The discriminant value for
	/// [`atomic::Ordering::Release`].
	///
	/// [`atomic::Ordering::Release`]: core::sync::atomic::Ordering::Release
	pub(super) const ATOMIC_ORDERING_RELEASE: u8 = 1;

	/// The discriminant value for
	/// [`atomic::Ordering::SeqCst`].
	///
	/// [`atomic::Ordering::SeqCst`]: core::sync::atomic::Ordering::SeqCst
	pub(super) const ATOMIC_ORDERING_SEQ_CST: u8 = 4;

	/// The discriminant value for
	/// [`cmp::Ordering::Equal`].
	///
	/// [`core::cmp::Ordering::Equal`]: core::cmp::Ordering::Equal
	pub(super) const CMP_ORDERING_EQUAL: i8 = 0;

	/// The discriminant value for
	/// [`cmp::Ordering::Greater`].
	///
	/// [`core::cmp::Ordering::Greater`]: core::cmp::Ordering::Greater
	pub(super) const CMP_ORDERING_GREATER: i8 = 1;

	/// The discriminant value for
	/// [`cmp::Ordering::Less`].
	///
	/// [`core::cmp::Ordering::Less`]: core::cmp::Ordering::Less
	pub(super) const CMP_ORDERING_LESS: i8 = -1;

	/// The discriminant value for [`IpAddr::V4`].
	///
	/// [`IpAddr::V4`]: core::net::IpAddr::V4
	pub(super) const IP_ADDR_V4: u8 = 4;

	/// The discriminant value for [`IpAddr::V6`].
	///
	/// [`IpAddr::V6`]: core::net::IpAddr::V6
	pub(super) const IP_ADDR_V6: u8 = 6;

	/// The discriminant value for [`Option::None`].
	pub(super) const OPTION_NONE: u8 = 0;

	/// The discriminant value for [`Option::Some`].
	pub(super) const OPTION_SOME: u8 = 1;

	/// The discriminant value for [`Shutdown::Both`].
	///
	/// [`Shutdown::Both`]: std::net::Shutdown::Both
	#[cfg(feature = "std")]
	pub(super) const SHUTDOWN_BOTH: u8 = SHUTDOWN_READ | SHUTDOWN_WRITE;

	/// The discriminant value for [`Shutdown::Read`].
	///
	/// [`Shutdown::Read`]: std::net::Shutdown::Read
	#[cfg(feature = "std")]
	pub(super) const SHUTDOWN_READ: u8 = 1;

	/// The discriminant value for [`Shutdown::Write`].
	///
	/// [`Shutdown::Write`]: std::net::Shutdown::Write
	#[cfg(feature = "std")]
	pub(super) const SHUTDOWN_WRITE: u8 = 2;

	/// The discriminant value for [`SocketAddr::V4`].
	///
	/// [`SocketAddr::V4`]: core::net::SocketAddr::V4
	pub(super) const SOCKET_ADDR_V4: u8 = 4;

	/// The discriminant value for [`SocketAddr::V6`].
	///
	/// [`SocketAddr::V6`]: core::net::SocketAddr::V6
	pub(super) const SOCKET_ADDR_V6: u8 = 6;

	/// The discriminant value for [`Result::Ok`].
	pub(super) const RESULT_OK: u8 = 0;

	/// The discriminant value for [`Result::Err`].
	pub(super) const RESULT_ERR: u8 = 1;
}