tola_caps/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(clippy::crate_in_macro_def)]
3
4// Feature flags handled:
5// - std: default, enables std library
6// - alloc: enables alloc types in no_std
7// - specialize: enables specialization macros
8
9//! # tola-caps
10//!
11//! Capability system using 16-ary type-level trie with hash-stream routing.
12//!
13//! **Type-level capability system for Rust.**
14//!
15//! ## Architecture
16//!
17//! `tola-caps` allows types to act as sets of keys (Capabilities).
18//!
19//! ### 1. Routing
20//! We use a **64-bit FNV-1a Hash** of the capability's name to route it into a 16-ary Radix Trie.
21//!
22//! ```text
23//! Type Name -> FNV Hash (u64) -> Nibble Stream -> Trie Path (Node16)
24//! ```
25//!
26//! ### 2. Identity (Finger Tree)
27//! Hash collisions are resolved via **Finger Tree Identities**.
28//! Each capability encodes its full path (`Name@file:line:col`) as a Finger Tree:
29//!
30//! ```text
31//! FDeep<Measure, Prefix, Spine, Suffix>
32//!   |        |        |        |
33//!   XOR hash  First   Middle    Last
34//!   (O(1))   1-4 B    bytes    1-4 B
35//! ```
36//!
37//! ### 3. Comparison
38//! Three-layer comparison: Measure (O(1)) -> Prefix -> Suffix -> Spine (O(log n))
39//!
40//! ### 4. Fallback Tricks
41//! We use **Autoref/Method Priority** to achieve trait detection and stable specialization.
42//!
43//! ```text
44//! +-------------------------------------------------------------------+
45//! |  Layer 0: Primitives                                              |
46//! |  - Nibble (X0-XF), Stream, Identity (Byte/Char), Finger Tree      |
47//! +-------------------------------------------------------------------+
48//!                                |
49//!                                v
50//! +-------------------------------------------------------------------+
51//! |  Layer 1: Trie Core                                               |
52//! |  - Node16, Leaf, Bucket (Storage)                                 |
53//! |  - InsertAt, RemoveAt, Evaluate (Logic)                           |
54//! +-------------------------------------------------------------------+
55//!                                |
56//!                                v
57//! +-------------------------------------------------------------------+
58//! |  Layer 2: User API                                                |
59//! |  - macros (caps!, caps_check!), AutoCaps, Feature Detection       |
60//! +-------------------------------------------------------------------+
61//! ```
62//!
63//! ## Features
64//!
65//! - **O(1) Compile-time Lookup**: Type-level hash-based routing via 16-ary radix trie
66//! - **Zero Runtime Overhead**: All capability checks happen at compile time
67//! - **Infinite Extensibility**: Define capabilities anywhere, no central registry needed
68//! - **Clean API**: No `_` placeholders or turbofish in function signatures
69//!
70//! ## Quick Start
71//!
72//! ```ignore
73//! use tola_caps::prelude::*;
74//!
75//! // Define capabilities with derive (auto-generates hash stream)
76//! #[derive(Capability)]
77//! struct CanRead;
78//!
79//! #[derive(Capability)]
80//! struct CanWrite;
81//!
82//! // Build capability set
83//! type MyCaps = caps![CanRead, CanWrite];
84//!
85//! // Function with capability requirements
86//! fn process<C>()
87//! where
88//!     C: Evaluate<CanRead, Out = Present>,
89//! { }
90//!
91//! // Call with explicit type
92//! process::<MyCaps>();
93//! ```
94
95// #![cfg_attr(not(test), no_std)] - Handled by top-level attribute
96
97// Allow `::tola_caps` to work inside the crate itself
98extern crate self as tola_caps;
99
100#[cfg(feature = "alloc")]
101extern crate alloc;
102
103// Re-export paste for define_trait_cap! macro
104pub use paste;
105
106// =============================================================================
107// Layer 0: Primitives (no dependencies)
108// =============================================================================
109pub mod primitives;
110
111// =============================================================================
112// Layer 1: Trie Core
113// =============================================================================
114pub mod trie;
115
116// =============================================================================
117// Layer 2: Std Trait Detection
118// =============================================================================
119// TEMPORARILY DISABLED for debugging - this generates massive amounts of code
120#[cfg(feature = "detect")]
121pub mod detect;
122
123// Placeholder module when detect is disabled
124#[cfg(not(feature = "detect"))]
125pub mod detect {
126    use core::marker::PhantomData;
127
128    // Minimal stub for compatibility
129    pub trait AutoCaps {
130        const IS_CLONE: bool = false;
131        const IS_COPY: bool = false;
132        const IS_DEBUG: bool = false;
133        const IS_DEFAULT: bool = false;
134        const IS_SEND: bool = false;
135        const IS_SYNC: bool = false;
136    }
137    pub trait AutoCapSet {
138        type Out;
139    }
140    // Use PhantomData to consume T
141    pub type Cap<T> = PhantomData<T>;
142    pub struct InsertIf<S, Cap, const B: bool>(PhantomData<(S, Cap)>);
143    pub struct InsertIfType<S, Cap, B>(PhantomData<(S, Cap, B)>);
144}
145
146// =============================================================================
147// Layer 3: Specialization Sugar
148// =============================================================================
149pub mod spec;
150
151// Syntax macros (dispatch!, specialize_trait!, impl_specialized!)
152pub mod syntax_macros;
153
154// =============================================================================
155// Re-exports at Crate Root
156// =============================================================================
157
158// Re-export core types from trie and primitives at crate root
159pub use trie::*;
160pub use primitives::bool::{Bool, Present, Absent, BoolAnd, BoolOr, BoolNot};
161pub use primitives::nibble::{
162    Nibble, NibbleEq,
163    X0, X1, X2, X3, X4, X5, X6, X7,
164    X8, X9, XA, XB, XC, XD, XE, XF,
165};
166pub use primitives::stream::{
167    HashStream, GetTail, ConstStream, AltStream, Cons,
168    Z, S, DefaultMaxDepth, StreamEq, StreamEqDispatch, D0, D16, Peano,
169    HashStream16,
170};
171
172// Backward compatibility aliases
173pub mod std_caps {
174    pub use crate::detect::*;
175}
176pub mod capability {
177    pub use crate::trie::*;
178    pub use crate::Evaluate;
179}
180
181// Re-export proc-macros
182pub use macros::{cap, caps, caps_bound, caps_check, specialize, specialize_inherent, specialization, derive_trait_cap, Capability, AutoCaps, trait_autocaps, define_type_cap, name_stream, make_routing_stream, make_identity_bytes, __internal_make_identity};
183
184// =============================================================================
185// Declarative Macro Bridge for #[derive(Capability)]
186// =============================================================================
187//
188// Three-layer macro architecture to get module_path!() into proc-macros:
189// 1. #[derive(Capability)] (proc-macro) generates __impl_capability! call
190// 2. __impl_capability! (this decl-macro) expands concat!(module_path!(), ...)
191// 3. make_routing_stream! (proc-macro) receives string literal
192
193/// Internal macro bridge - DO NOT USE DIRECTLY.
194/// Use #[derive(Capability)] instead.
195#[macro_export]
196#[doc(hidden)]
197macro_rules! __impl_capability {
198    ($ty:ty, $name:expr) => {
199        impl $crate::Capability for $ty {
200            // Stream: hash-based routing for trie navigation
201            type Stream = $crate::make_routing_stream!(concat!(module_path!(), "::", $name));
202
203            // Identity: Type-level character list for exact comparison
204            type Identity = $crate::__make_identity_from_str!(concat!(module_path!(), "::", $name));
205
206            type At<D: $crate::Peano> = <<Self::Stream as $crate::GetTail<D>>::Out as $crate::HashStream>::Head
207            where Self::Stream: $crate::GetTail<D>;
208        }
209    };
210}
211
212/// Helper macro to convert concat!() result to proc-macro call
213#[macro_export]
214#[doc(hidden)]
215macro_rules! __make_identity_from_str {
216    ($s:expr) => {
217        $crate::__internal_make_identity!($s)
218    };
219}
220
221/// Common items for the capability system.
222pub mod prelude {
223    pub use crate::trie::{
224        // Core Traits
225        Capability, Evaluate, With, Inspect,
226        // Set Operations
227        SetUnion, SetIntersect, SupersetOf,
228    };
229    pub use crate::detect::AutoCaps;
230    #[cfg(feature = "detect")]
231    pub use crate::detect::{
232        AutoCapSet, Cap,
233        // All capability markers
234        IsClone, IsCopy, IsDebug, IsDefault, IsSend, IsSync,
235        IsEq, IsPartialEq, IsOrd, IsPartialOrd, IsHash,
236        IsDisplay, IsSized, IsUnpin,
237    };
238    pub use macros::{caps, caps_bound, caps_check, Capability};
239    // Note: with!, union!, intersect!, check! are #[macro_export] so they're at crate root
240}
241