oct 0.36.2

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

//! Octonary transcoder.
//!
//! This library provides facilities for safe (and
//! hopefully sound) transmutations of Rust objects,
//! mainly to and from octonary (bytewise)
//! representations. These transformations may be
//! done in two ways:
//!
//! * In-place transmutations: Objects can be
//!   reinterpret between different types in-place.
//! * Serialisations: Objects can also be serialise
//!   into a portable representation.
//!
//! These interfaces are generally safe and are
//! designed so that most programmes can completely
//! avoid any unsafe code. The only unsafe
//! interfaces provided are traits and the low-level
//! [`transmute_unchecked`] function.
//!
//! # Security
//!
//! Do note that this project is still relatively
//! early in its development. But even with the
//! hundreds of man-hours of development so far, I
//! very much recommend auditing it before using it
//! in production (nevertheless the so-far soundness
//! holes uncovered.) I would not *yet* use this
//! project in critical systems – although I
//! am confident that it will become realistic to do
//! so at some point.
//!
//! # Interface stability and versioning
//!
//! Breaking changes are common, and usage of this
//! library will require continuous maintenance so
//! as to avoid becoming stuck on an unmaintained
//! major release. Nonetheless, core designs are
//! likely to remain more or less the same, and most
//! breakage will be in the form of lesser,
//! syntactical changes, e.g. identifier renaming or
//! parameter reordering.
//!
//! The octonary format used by serialisations is
//! not stabilised and are not on track to become
//! stabilised. Instead, users should use in-place
//! transmutations or custom serialisers for
//! specific specifications.
//!
//! # Copyright and licence
//!
//! Copyright © 2024‐2026 Gabriel
//! Bjørnager Jensen.
//!
//! This library is distributed under either an MIT
//! licence or version 2.0 of the Apache License, at
//! your option. See `LICENCE-MIT.txt` and
//! `LICENCE-APACHE.txt` for more information.
//!
//! SPDX identifier: `MIT OR Apache-2.0`

#![doc(html_logo_url = "https://codeberg.org/bjoernager/oct/raw/branch/master/DOC-ICON.svg")]

#![no_std]

#![cfg_attr(feature = "unstable_docs", allow(internal_features))]

#![cfg_attr(feature = "ascii", feature(ascii_char))]

#![cfg_attr(all(target_has_atomic = "128", feature = "atomic_u128_i128"), feature(integer_atomics))]

#![cfg_attr(feature = "bstr", feature(bstr))]

#![cfg_attr(feature = "f128", feature(f128))]

#![cfg_attr(feature = "f16", feature(f16))]

#![cfg_attr(
	all(
		any(
			target_arch = "aarch64",
			target_arch = "arm64ec",
			target_feature = "v7",
		),
		feature = "f16",
	),
	feature(
		stdarch_neon_f16,
	),
)]

#![cfg_attr(feature = "simd", feature(portable_simd))]

#![cfg_attr(feature = "unstable_docs", feature(doc_cfg, rustdoc_internals))]

extern crate self as oct;

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(feature = "std")]
extern crate std;

pub mod serdes;

mod from_octets;
mod immutable;
mod init;
mod into_octets;
mod outlay;
mod transmute;
mod zeroable;

pub use from_octets::FromOctets;
pub use immutable::Immutable;
pub use init::Init;
pub use into_octets::IntoOctets;
pub use outlay::Outlay;
pub use transmute::{
	transmute,
	transmute_mut,
	transmute_mut_with_metadata,
	transmute_ref,
	transmute_ref_with_metadata,
	transmute_unchecked,
};
pub use zeroable::Zeroable;

/// Implements [`FromOctets`] for the given type.
///
/// [`FromOctets`]: trait@FromOctets
///
/// # Examples
///
/// Any type can derive [`FromOctets`] -- as long as
/// all member fields also implement it.
///
/// [`FromOctets`]: trait@FromOctets
///
/// ```rust
/// use oct::{FromOctets, Zeroable};
///
/// #[derive(FromOctets, Zeroable)]
/// struct Reminder {
///     timestamp: i64,
/// }
/// ```
#[cfg(feature = "proc_macro")]
#[doc(inline)]
pub use oct_macros::FromOctets;

/// Implements [`Immutable`] for the given type.
///
/// [`Immutable`]: trait@Immutable
///
/// # Examples
///
/// Most types can simply derive [`Immutable`],
/// provided that all fields also implement
/// `Immutable`:
///
/// [`Immutable`]: trait@Immutable
///
/// ```rust
/// use oct::Immutable;
///
/// #[derive(Immutable)]
/// struct InteriourImmutableI32 {
///     value: i32,
/// }
/// ```
///
/// Types that contain [`UnsafeCell`] (or other cell
/// types) can thus not derive `Immutable`:
///
/// [`UnsafeCell`]: core::cell::UnsafeCell
///
/// ```rust,compile_fail
/// use core::cell::Cell;
/// use oct::Immutable;
///
/// #[derive(Immutable)]
/// struct InteriourMutableI32 {
///     value: Cell<i32>,
/// }
/// ```
#[cfg(feature = "proc_macro")]
#[doc(inline)]
pub use oct_macros::Immutable;

/// Implements [`Zeroable`] for the given type.
///
/// [`Zeroable`]: trait@Zeroable
///
/// # Examples
///
/// Enumerations must have a variant that uses `0`
/// as its discriminant:
///
/// ```rust
/// use oct::Zeroable;
///
/// #[repr(u8)]
/// #[derive(Zeroable)]
/// enum ExplicitZero {
///     Zero = 0,
/// }
///
/// #[repr(i8)]
/// #[derive(Zeroable)]
/// enum ImplicitZero {
///     NegativeOne = -1,
///     Zero,
/// }
/// ```
///
/// Thus, the following is rejected:
///
/// ```rust,compile_fail
/// use oct::Zeroable;
///
/// #[repr(i32)]
/// #[derive(Zeroable)]
/// enum NoZeroDiscriminant {
///     NegativeTwo = -2,
///     NegativeOne,
///     One         = 1,
/// }
/// ```
#[cfg(feature = "proc_macro")]
#[doc(inline)]
pub use oct_macros::Zeroable;