nlist/lib.rs
1//! Provides an [inline-allocated list] which statically tracks its length,
2//! and type-based [integer]/[boolean] representations which
3//! don't require (additional) bounds for operators.
4//!
5//! # Example
6//!
7//! ### Splitting and recombining
8//!
9//! This example shows how NLists can be split and recombined in const,
10//! even if the length is generic,
11//! so long as the length is known to be greater than the split index.
12//!
13//! ```rust
14//! use nlist::{NList, Peano, PeanoInt, nlist, peano};
15//!
16//! const LIST: NList<u128, Peano!(7)> = transform(nlist![3, 5, 8, 13, 21, 34, 55]);
17//!
18//! assert_eq!(LIST, nlist![21, 34, 55, 103, 105, 108, 113]);
19//!
20//! type SplitIndex = Peano!(4);
21//!
22//! const fn transform<L>(
23//! list: NList<u128, peano::Add<SplitIndex, L>>,
24//! ) -> NList<u128, peano::Add<SplitIndex, L>>
25//! where
26//! L: PeanoInt,
27//! {
28//! // if we use `let` to destructure instead of `konst::destructure`,
29//! // we get a "destructor cannot be evaluated at compile-time" error as of Rust 1.83
30//! konst::destructure!{(before, after) = list.split_at::<SplitIndex>()}
31//!
32//! // math spice: using arithmetic properties to coerce equal generic lengths.
33//! //
34//! // Alternatively, you can pass `peano::eq().unwrap_eq()` to `coerce_len`
35//! // for an easier, but panic prone, approach:
36//! // ```
37//! // return after.concat(map_add_100(before)).coerce_len(peano::eq().unwrap_eq())
38//! // ```
39//! //
40//! // coercing `NList<u128, L - 0>` to `NList<u128, L>`
41//! let coerced_after = after.coerce_len(peano::proofs::sub_identity::<L>());
42//!
43//! coerced_after.concat(map_add_100(before))
44//! // coercing `NList<u128, L + SplitIndex>` to `NList<u128, SplitIndex + L>`
45//! .coerce_len(peano::proofs::commutative_add::<L, SplitIndex>())
46//! }
47//!
48//! // Adds 100 to all elemenst of an NList
49//! const fn map_add_100<L: PeanoInt>(list: NList<u128, L>) -> NList<u128, L> {
50//! nlist::rec_map!(list, |elem, rest| (elem + 100, map_add_100(rest)))
51//! }
52//! ```
53//!
54//! # Crate features
55//!
56//! - `"alloc"`(enabled by default): enables methods that take or return [`Vec`]
57//!
58//!
59//! # No-std support
60//!
61//! `nlist` is `#![no_std]`, it can be used anywhere Rust can be used.
62//!
63//! # Minimum Supported Rust Version
64//!
65//! `nlist` requires Rust 1.83.0.
66//!
67//!
68//! [inline-allocated list]: crate::NList
69//! [integer]: crate::peano::PeanoInt
70//! [boolean]: crate::boolean::Boolean
71//! [`NList`]: crate::NList
72//! [`Vec`]: alloc::vec::Vec
73
74#![forbid(unsafe_code)]
75#![deny(missing_docs)]
76#![deny(unused_results)]
77#![no_std]
78
79#[cfg(feature = "alloc")]
80extern crate alloc;
81
82#[doc(no_inline)]
83pub use typewit;
84
85#[macro_use]
86mod macros;
87
88pub mod boolean;
89
90pub mod peano;
91
92mod nlist;
93
94mod imply_trait;
95
96pub mod receiver;
97
98pub use crate::{
99 nlist::*,
100 peano::{PeanoInt, PeanoWit, PlusOne, Zero},
101};
102
103
104
105
106#[doc(hidden)]
107pub mod __ {
108 pub use konst::destructure;
109
110 pub use core::primitive::bool;
111
112 pub use core::compile_error;
113}
114
115
116#[cfg(doctest)]
117#[doc = include_str!("../README.md")]
118pub struct ReadmeTest;
119