Skip to main content

reflect_nat/
lib.rs

1#![deny(unsafe_code)]
2
3//! Ready-made type-level values: Peano naturals, booleans, and
4//! heterogeneous lists, all implementing
5//! [`Reflect`](reify_reflect_core::Reflect).
6//!
7//! Where [`reify-reflect-core`](https://docs.rs/reify-reflect-core)
8//! defines the [`Reflect`](reify_reflect_core::Reflect) trait and the
9//! [`RuntimeValue`](reify_reflect_core::RuntimeValue) vocabulary, this
10//! crate provides the most useful concrete instances of that trait, the
11//! ones you reach for first when prototyping type-level code.
12//!
13//! All of these types are zero-sized: they exist only at compile time
14//! and disappear at runtime. The [`Reflect`](reify_reflect_core::Reflect)
15//! impls are what give you a runtime handle on the value they encode.
16//!
17//! # What's in here
18//!
19//! ## Peano naturals
20//!
21//! - [`Z`] is zero, [`S<N>`] is "successor of `N`".
22//! - [`Add`], [`Mul`], and [`Lt`] perform type-level arithmetic.
23//! - [`N0`] through [`N8`] are convenience aliases for the small numbers.
24//! - The [`Nat`] trait gives you a runtime [`u64`] for any of these types,
25//!   and the [`Reflect`](reify_reflect_core::Reflect) impl produces a
26//!   [`RuntimeValue::Nat`](reify_reflect_core::RuntimeValue::Nat).
27//!
28//! ## Type-level booleans
29//!
30//! - [`True`] and [`False`].
31//! - [`Not`], [`And`], [`Or`] perform compile-time boolean logic at the
32//!   trait level.
33//! - Both reflect to a plain [`prim@bool`].
34//!
35//! ## Heterogeneous lists
36//!
37//! - [`HNil`] is the empty list, [`HCons<H, T>`] is a cons cell.
38//! - The [`HList`] trait exposes [`len()`](HList::len) and
39//!   [`is_empty()`](HList::is_empty) at the type level.
40//! - When every element implements
41//!   [`Reflect<Value = RuntimeValue>`](reify_reflect_core::Reflect),
42//!   the whole HList reflects to a `Vec<RuntimeValue>`.
43//!
44//! ## Optional bridges (feature-gated)
45//!
46//! - `frunk`: interoperate with `frunk`'s `HList`.
47//! - `typenum`: bridge between [`Nat`] and `typenum`'s `Unsigned`.
48//!
49//! # Examples
50//!
51//! ```
52//! use reflect_nat::{Z, S, True, HNil, HCons};
53//! use reify_reflect_core::{Reflect, RuntimeValue};
54//!
55//! // Type-level natural: 3
56//! type Three = S<S<S<Z>>>;
57//! assert_eq!(Three::reflect(), RuntimeValue::Nat(3));
58//!
59//! // Type-level boolean
60//! assert_eq!(True::reflect(), true);
61//!
62//! // Type-level HList: [3, 0]
63//! type MyList = HCons<Three, HCons<Z, HNil>>;
64//! assert_eq!(
65//!     MyList::reflect(),
66//!     vec![RuntimeValue::Nat(3), RuntimeValue::Nat(0)]
67//! );
68//! ```
69//!
70//! See also: [`reflect-derive`](https://docs.rs/reflect-derive) for
71//! `#[derive(Reflect)]` on your own structs and enums (which can include
72//! the types from this crate as fields), and
73//! [`const-reify`](https://docs.rs/const-reify) for going the other
74//! direction (runtime `u64` to const generic).
75
76mod bool;
77mod hlist;
78mod nat;
79
80#[cfg(feature = "frunk")]
81pub mod frunk_bridge;
82#[cfg(feature = "typenum")]
83pub mod typenum_bridge;
84
85pub use self::bool::*;
86pub use hlist::*;
87pub use nat::*;