Skip to main content

lexe_std/
lib.rs

1//! # `lexe-std`
2//!
3//! This crate contains "std extensions" which other Lexe crates can use without
4//! having to pull in any dependencies.
5//!
6//! Traits, macros, copies of unstable `std` APIs, a small number of types, are
7//! all fair game so long as they do NOT depend on anything outside of [`std`].
8
9// Re-export `std` for use by macros.
10#[doc(hidden)]
11pub use std;
12
13/// `[u8; N]` array functions.
14pub mod array;
15/// Exponential backoff.
16pub mod backoff;
17/// Utilities for use in `const` fns and expressions.
18pub mod const_utils;
19/// `fmt` extensions.
20pub mod fmt;
21/// Iterator extensions.
22pub mod iter;
23/// Path extensions.
24pub mod path;
25/// String utilities.
26pub mod string;
27
28/// A trait which allows us to apply functions (including tuple enum variants)
29/// to non-[`Iterator`]/[`Result`]/[`Option`] values for cleaner iterator-like
30/// chains. It exposes an [`apply`] method and is implemented for all `T`.
31///
32/// For example, instead of this:
33///
34/// ```ignore
35/// # use lexe_common::ln::amount::Amount;
36/// let value_sat_u64 = 100_000u64; // Pretend this is from LDK
37/// let value_sat_u32 = u32::try_from(value_sat_u64)
38///     .expect("Amount shouldn't have overflowed");
39/// let maybe_value = Some(Amount::from_sats_u32(value_sat_u32));
40/// ```
41///
42/// We can remove the useless `value_sat_u32` intermediate variable:
43///
44/// ```ignore
45/// # use lexe_common::ln::amount::Amount;
46/// # use lexe_common::Apply;
47/// let value_sat_u64 = 100_000u64; // Pretend this is from LDK
48/// let maybe_value = u32::try_from(value_sat_u64)
49///     .expect("Amount shouldn't have overflowed")
50///     .apply(Amount::from_sats_u32)
51///     .apply(Some);
52/// ```
53///
54/// Without having to add use nested [`Option`]s / [`Result`]s which can be
55/// confusing:
56///
57/// ```ignore
58/// # use lexe_common::ln::amount::Amount;
59/// let value_sat_u64 = 100_000u64; // Pretend this is from LDK
60/// let maybe_value = u32::try_from(value_sat_u64)
61///     .map(Amount::from_sats_u32)
62///     .map(Some)
63///     .expect("Amount shouldn't have overflowed");
64/// ```
65///
66/// Overall, this trait makes it easier to both (1) write iterator chains
67/// without unwanted intermediate variables and (2) write them in a way that
68/// maximizes clarity and readability, instead of having to reorder our
69/// `.transpose()` / `.map()`/ `.expect()` / `.context("...")?` operations
70/// to "stay inside" the function chain.
71///
72/// [`apply`]: Self::apply
73pub trait Apply<F, T> {
74    fn apply(self, f: F) -> T;
75}
76
77impl<F, T, U> Apply<F, U> for T
78where
79    F: FnOnce(T) -> U,
80{
81    #[inline]
82    fn apply(self, f: F) -> U {
83        f(self)
84    }
85}