compost/lib.rs
1//! # Overview
2//!
3//! This library exposes [`decompose!`](crate::decompose), a macro to decompose tuples into tuples
4//! containing a subset of their values.
5//!
6//! ```
7//! use compost::decompose;
8//!
9//! // Pack all your context into a tuple...
10//! let mut cx = (&mut 1u32, &2u8, (&3u16, &mut 'e', "f", &mut [1, 2, 3]));
11//!
12//! // And cal your target function!
13//! consumer(decompose!(cx));
14//!
15//! // Define functions taking tuples of context...
16//! fn consumer_2((a, b, c, d, e): (&u32, &str, &char, &f32, &i8)) {
17//! dbg!(a, b, c, d, e);
18//! }
19//!
20//! fn consumer_3((f, g, h): (&char, &str, &mut [u8; 3])) {
21//! dbg!(f, g, h);
22//! }
23//!
24//! fn consumer(mut cx: (&mut u32, &char, &str, &mut [u8; 3])) {
25//! // Bring types into scope and produce a remainder tuple.
26//! decompose!(cx => rest & {
27//! char: &char,
28//! bytes: &mut [u8; 3],
29//! });
30//!
31//! // Combine contexts...
32//! let mut rest = (rest, (&mut 4.3f32, &-4i8), &mut 5i16);
33//!
34//! // ...and forward them to further functions.
35//! consumer_2(decompose!(rest));
36//!
37//! // ...all without invalidating existing borrows!
38//! dbg!(char, bytes);
39//!
40//! // Reborrow the original context after its borrows have expired.
41//! consumer_3(decompose!(cx));
42//! }
43//! ```
44//!
45//! See [`decompose!`](crate::decompose)'s documentation for more details on the precise semantics and
46//! limitations of the macro.
47//!
48//! ## Features
49//!
50//! Yes, this library...
51//!
52//! - Supports reborrowing (i.e. `decompose!` does not consume its input. Once you're done
53//! with the borrow, you can reuse the original tuple).
54//! - Produces (admittedly pretty ugly) errors at compile time if the tuple cannot be decomposed.
55//! - Supports borrowing mutable, immutable, and smart-pointer wrapped (so long as they implement
56//! [`Deref`](::core::ops::Deref)) components.
57//! - Supports borrowing from nested tuple trees, allowing you to borrow from an arbitrary number of
58//! components simultaneously and to quickly merge multiple context tuples by packing them into a
59//! single tuple.
60//! - Supports borrowing generic elements without failing spuriously on monomorphization.
61//! - Relies on type inference rather than `TypeId`, allowing the macro to operate on non-`'static` types.
62//! - Supports `no_std` environments and does not rely on unsafe code.
63//! - Has zero runtime dependencies.
64//!
65
66#![no_std]
67#![forbid(unsafe_code)]
68
69// Necessary to avoid ambiguous doc link to `crate::decompose`.
70#[path = "decompose.rs"]
71mod decompose_impl;
72
73#[doc(hidden)]
74pub mod macro_internal {
75 pub use super::decompose_impl::*;
76 pub use core::option::Option::{None, Some};
77}