constmuck/
lib.rs

1//! Const equivalents of many [`bytemuck`] functions.
2//!
3//! `constmuck` uses [`bytemuck`'s traits],
4//! any type that implements those traits can be used with the
5//! relevant functions from this crate.
6//!
7//! Because the `*_alt` functions are `const fn`s,
8//! they can't inspect the address of the reference parameter.
9//! This differs from their [`bytemuck`] equivalents,
10//! which use the address to determine alignment.
11//!
12//! # Examples
13//!
14//! These examples use bytemuck's derives to show how users don't need to
15//! write `unsafe` to use this crate,
16//! and use the [`konst`] crate to make writing the const functions easier.
17//!
18//! ### Contiguous
19//!
20//! This example demonstrates constructing an enum from its representation.
21//!
22//! ```rust
23//!
24//! use constmuck::Contiguous;
25//!
26//! use konst::{array, try_opt};
27//!
28//! fn main() {
29//!     const COLORS: Option<[Color; 5]> = Color::from_array([3, 4, 1, 0, 2]);
30//!     assert_eq!(
31//!         COLORS,
32//!         Some([Color::White, Color::Black, Color::Blue, Color::Red, Color::Green]),
33//!     );
34//!
35//!     const NONE_COLORS: Option<[Color; 4]> = Color::from_array([1, 2, 3, 5]);
36//!     assert_eq!(NONE_COLORS, None);
37//! }
38//!
39//! #[repr(u8)]
40//! #[derive(Debug, PartialEq, Eq, Contiguous, Copy, Clone)]
41//! pub enum Color {
42//!     Red = 0,
43//!     Blue,
44//!     Green,
45//!     White,
46//!     Black,
47//! }
48//!
49//! impl Color {
50//!     pub const fn from_int(n: u8) -> Option<Self> {
51//!         constmuck::contiguous::from_integer(n)
52//!     }
53//!     pub const fn from_array<const N: usize>(input: [u8; N]) -> Option<[Self; N]> {
54//!         // `try_opt` returns from `from_array` on `None`,
55//!         // because `konst::array::map` allows the passed-in expression
56//!         // to return from the surrounding named function.
57//!         Some(array::map!(input, |n| try_opt!(Self::from_int(n))))
58//!     }
59//! }
60//!
61//!
62//! ```
63//!
64//! ### Wrapper
65//!
66//! This example demonstrates a type that wraps a `[T]`, constructed by reference.
67//!
68//! ```rust
69//!
70//! use constmuck::TransparentWrapper;
71//!
72//! fn main() {
73//!     const SLICE: &[u32] = &[3, 5, 8, 13, 21];
74//!     const WRAPPER: &SliceWrapper<u32> = SliceWrapper::new(SLICE);
75//!
76//!     const SUM: u64 = WRAPPER.sum();
77//!     assert_eq!(SUM, 50);
78//!
79//!     const FIRST_EVEN: Option<(usize, u32)> = WRAPPER.find_first_even();
80//!     assert_eq!(FIRST_EVEN, Some((2, 8)));
81//! }
82//!
83//! #[repr(transparent)]
84//! #[derive(Debug, PartialEq, Eq, TransparentWrapper)]
85//! pub struct SliceWrapper<T>(pub [T]);
86//!
87//! impl<T> SliceWrapper<T> {
88//!     // Using `constmuck` allows safely defining this function as a `const fn`
89//!     pub const fn new(reff: &[T]) -> &Self {
90//!         constmuck::wrapper::wrap_ref!(reff)
91//!     }
92//! }
93//!
94//! impl SliceWrapper<u32> {
95//!     pub const fn sum(&self) -> u64 {
96//!         konst::iter::eval!(&self.0,copied(),fold(0, |l, r| l + r as u64))
97//!     }
98//!     pub const fn find_first_even(&self) -> Option<(usize, u32)> {
99//!         konst::iter::eval!(&self.0,copied(),enumerate(),find(|(i, n)| *n % 2 == 0))
100//!     }
101//! }
102//!
103//!
104//! ```
105//!
106//! # Additional checks
107//!
108//! The `"debug_checks"` crate feature (which is disabled by default)
109//! enables additional assertions in `constmuck` functions,
110//! these assertions panic in some cases where unsound impls of [`bytemuck`] traits
111//! would have caused Undefined Behavior.
112//!
113//! # Features
114//!
115//! These are the features of this crate:
116//!
117//! - `"derive"`(disabled by default):
118//! Enables `bytemuck`'s `"derive"` feature and reexports its derives.
119//!
120//! - `"debug_checks"`(disabled by default):
121//! Enables [additional safety checks](#additional-checks) for detecting some
122//! Undefined Behavior.
123//!
124//! - `"rust_1_75"` (disabled by default):
125//! allows [`constmuck::zeroed`] to construct types of any size.
126//!
127//! - `"rust_latest_stable"` (disabled by default):
128//! enables all `"rust_1_*"` features.
129//!
130//! # No-std support
131//!
132//! `constmuck` is `#![no_std]`, it can be used anywhere Rust can be used.
133//!
134//! # Minimum Supported Rust Version
135//!
136//! `constmuck` requires Rust 1.65.0.
137//!
138//! You can use the `"rust_latest_stable"` crate feature to get
139//! all items and functionality that requires stable Rust versions after 1.65.0.
140//!
141//! [`bytemuck`]: bytemuck
142//! [`bytemuck`'s traits]: bytemuck#traits
143//! [`konst`]: https://docs.rs/konst/0.3/konst/index.html
144//! [`contiguous`]: ./contiguous/index.html
145//! [`wrapper`]: ./wrapper/index.html
146//! [`constmuck::zeroed`]: crate::zeroed
147
148#![no_std]
149#![deny(unused_results)]
150#![deny(clippy::missing_safety_doc)]
151#![deny(missing_debug_implementations)]
152#![deny(missing_docs)]
153#![deny(rustdoc::broken_intra_doc_links)]
154
155#[cfg(doctest)]
156#[doc = include_str!("../README.md")]
157pub struct ReadmeTest;
158
159#[macro_use]
160mod macros;
161
162pub mod contiguous;
163
164mod pod;
165
166mod slice_fns;
167
168pub mod wrapper;
169
170mod zeroable;
171
172#[doc(hidden)]
173pub mod __priv_utils;
174
175#[doc(no_inline)]
176pub use bytemuck::{
177    self, AnyBitPattern, Contiguous, NoUninit, Pod, PodCastError, TransparentWrapper, Zeroable,
178};
179
180pub use crate::{
181    pod::{
182        cast, cast_ref_alt, pod_read_unaligned, try_cast, try_cast_ref_alt, try_pod_read_unaligned,
183    },
184    slice_fns::{bytes_of, cast_slice_alt, try_cast_slice_alt},
185    zeroable::zeroed,
186};
187
188#[doc(hidden)]
189pub mod __ {
190    pub use core::mem::size_of;
191    pub use core::ops::Range;
192}
193
194use constmuck_internal::const_panic;