pub trait ChainLink: Sized {
// Provided methods
fn if<F>(self, condition: bool, change: F) -> Self
where F: FnOnce(Self) -> Self { ... }
fn if_else<A, B, T>(
self,
condition: bool,
change: A,
default_change: B,
) -> T
where A: FnOnce(Self) -> T,
B: FnOnce(Self) -> T { ... }
fn if_eval<P, F>(self, predicate: P, change: F) -> Self
where P: FnOnce(&Self) -> bool,
F: FnOnce(Self) -> Self { ... }
fn if_eval_else<P, A, B, T>(
self,
predicate: P,
change: A,
default_change: B,
) -> T
where P: FnOnce(&Self) -> bool,
A: FnOnce(Self) -> T,
B: FnOnce(Self) -> T { ... }
fn apply<F, T>(self, change: F) -> T
where F: FnOnce(Self) -> T { ... }
fn tap<F>(self, func: F) -> Self
where F: FnOnce(&Self) { ... }
fn mutated<F>(self, mutate: F) -> Self
where F: FnOnce(&mut Self) { ... }
}Provided Methods§
Sourcefn if<F>(self, condition: bool, change: F) -> Selfwhere
F: FnOnce(Self) -> Self,
fn if<F>(self, condition: bool, change: F) -> Selfwhere
F: FnOnce(Self) -> Self,
Applies the closure only if the condition is true.
§Examples
use hypotaxis::ChainLink;
use std::io::{stdout, IsTerminal};
std::process::Command::new("ls")
.arg("-t")
.r#if( stdout().is_terminal(), |command| command
.arg("-l")
)
.arg("-l")
.spawn()
.unwrap()
;Sourcefn if_else<A, B, T>(self, condition: bool, change: A, default_change: B) -> T
fn if_else<A, B, T>(self, condition: bool, change: A, default_change: B) -> T
Applies one closure if the condition is true,
otherwise applies the other closure. Other than
if() if_else() can change the return type.
use hypotaxis::ChainLink;
const ALWAYS_MORE: bool = true;
let longer = [1, 2, 3]
.into_iter()
.if_else(
ALWAYS_MORE,
|iter| iter.chain(vec![4, 5, 6]),
|iter| iter.chain(vec![])
)
.collect::<Vec<_>>()
;
assert_eq!(longer, [1, 2, 3, 4, 5, 6].to_vec())Sourcefn if_eval<P, F>(self, predicate: P, change: F) -> Self
fn if_eval<P, F>(self, predicate: P, change: F) -> Self
Applies the closure only if the predicate evaluates
to true.
§Examples
use hypotaxis::ChainLink;
let indexes = [1, 2, 3, 4, 5].to_vec();
let all_indexes = indexes
.if_eval(
|indexes| indexes[0] > 0,
|indexes| {
let mut indexes = indexes;
indexes.insert(0, 0);
indexes
}
)
;
assert_eq!(all_indexes, [0, 1, 2, 3, 4, 5].to_vec())Sourcefn if_eval_else<P, A, B, T>(
self,
predicate: P,
change: A,
default_change: B,
) -> T
fn if_eval_else<P, A, B, T>( self, predicate: P, change: A, default_change: B, ) -> T
Applies one closure if the predicate
evaluates to true, otherwise applies the
other closure. Other than
if_eval()
if_eval_else() can change the return type.
§Examples
use hypotaxis::ChainLink;
let data = [2.26, 3.32, 3.78, 9.39, 7.51];
let final_data = data
.if_eval_else(
|data| data.len() < 10,
|data| data
.into_iter()
.chain([10.0, f64::INFINITY].to_vec())
,
|data| data
.into_iter()
.chain([].to_vec())
)
.collect::<Vec<_>>()
;
assert_eq!(
final_data,
[2.26, 3.32, 3.78, 9.39, 7.51, 10.0, f64::INFINITY].to_vec()
)Sourcefn apply<F, T>(self, change: F) -> Twhere
F: FnOnce(Self) -> T,
fn apply<F, T>(self, change: F) -> Twhere
F: FnOnce(Self) -> T,
Applies the closure on the input value. This
can give you a block inside the method chain.
apply() is to a single type what
map()
is to
every item of an terator.
§Examples
use hypotaxis::ChainLink;
let appointment_day = 11;
let reminder_date = appointment_day
.apply(|day| day - 1)
.apply(|day| format!("2025.04.{day:#02}"))
;
assert_eq!(reminder_date, "2025.04.10");Sourcefn tap<F>(self, func: F) -> Selfwhere
F: FnOnce(&Self),
fn tap<F>(self, func: F) -> Selfwhere
F: FnOnce(&Self),
Gives access to the value inside a method chain.
§Examples
use hypotaxis::ChainLink;
let passcode = 33344850294026550922u128;
passcode
.tap(|passcode| {
#[cfg(debug_assertions)]
dbg!(*passcode);
})
.tap(|passcode| assert!(*passcode != 0))
;Sourcefn mutated<F>(self, mutate: F) -> Selfwhere
F: FnOnce(&mut Self),
fn mutated<F>(self, mutate: F) -> Selfwhere
F: FnOnce(&mut Self),
Returns the mutated value for further method calling.
§Examples
use hypotaxis::ChainLink;
#[derive(Debug, PartialEq)]
struct Person(String);
let names = ["Bob", "Alice", "Charlie"].to_vec();
let people_ordered = names
.mutated( |names| { names
.sort();
})
.into_iter()
.map(
|name| Person(name.to_string())
)
.collect::<Vec<_>>()
;
assert_eq!(people_ordered, [
Person("Alice".to_string()),
Person("Bob".to_string()),
Person("Charlie".to_string()),
])Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.