qubit_io/util/nz.rs
1// =============================================================================
2// Copyright (c) 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Compile-time `NonZeroUsize` construction helpers.
9
10use core::num::NonZeroUsize;
11
12/// Returns a [`NonZeroUsize`] from a known non-zero compile-time constant.
13///
14/// This helper panics during const evaluation when `value` is zero, surfacing
15/// the violation at build time. At runtime it remains a single conditional
16/// branch that the compiler folds away for constant inputs, eliminating the
17/// `unsafe { NonZeroUsize::new_unchecked(...) }` ceremony every concrete codec
18/// otherwise repeats.
19///
20/// # Parameters
21///
22/// - `value`: Non-zero item count.
23///
24/// # Returns
25///
26/// Returns a [`NonZeroUsize`] equal to `value`.
27///
28/// # Panics
29///
30/// Panics when `value` is zero.
31#[must_use]
32#[inline(always)]
33pub const fn nz(value: usize) -> NonZeroUsize {
34 match NonZeroUsize::new(value) {
35 Some(v) => v,
36 None => panic!("qubit_io::nz!(): value must be non-zero"),
37 }
38}
39
40/// Const-friendly wrapper around [`nz`] for use in expression position.
41///
42/// Prefer this macro over `unsafe { NonZeroUsize::new_unchecked(...) }` in
43/// `Codec::min_units_per_value` / `max_units_per_value` and similar sites
44/// where the item count is a compile-time constant: the panic branch is
45/// folded away and the call expands to a `NonZeroUsize` value the compiler
46/// can prove is non-zero.
47///
48/// # Examples
49///
50/// ```ignore
51/// use qubit_io::nz;
52/// const MAX: core::num::NonZeroUsize = qubit_io::nz!(4);
53/// ```
54#[macro_export]
55macro_rules! nz {
56 ($value:expr) => {{ $crate::nz_const($value) }};
57}
58
59/// Re-export of [`nz`] under the name expected by `nz!`.
60///
61/// The macro qualifies its expansion with `$crate::nz_const` so that callers
62/// can `use qubit_io::nz;` without also importing the function itself.
63///
64/// # Parameters
65///
66/// - `value`: Non-zero item count.
67///
68/// # Returns
69///
70/// Returns a [`NonZeroUsize`] equal to `value`.
71///
72/// # Panics
73///
74/// Panics when `value` is zero.
75#[must_use]
76#[inline(always)]
77pub const fn nz_const(value: usize) -> NonZeroUsize {
78 nz(value)
79}