use crate::unwrappable::Unwrappable;
pub trait Apply: Sized {
fn apply_keep<A, F: FnOnce(&mut Self) -> A>(mut self, f: F) -> (Self, A) {
let tmp = f(&mut self);
(self, tmp)
}
fn apply<A, F: FnOnce(&mut Self) -> A>(mut self, f: F) -> Self {
f(&mut self);
self
}
fn apply_unwrap<T, U: Unwrappable<T>, F: FnOnce(&mut Self) -> U>(mut self, f: F) -> Self {
Unwrappable::unwrap(f(&mut self));
self
}
}
impl<T: Sized> Apply for T {}
#[cfg(test)]
mod apply {
use super::*;
use std::collections::HashMap;
#[test]
fn build_hashmap() {
let left = HashMap::with_capacity(3)
.apply(|m| m.insert("foo", 101))
.apply(|m| m.insert("bar", 42))
.apply(|m| m.insert("baz", 1969));
let right = {
let mut tmp = HashMap::with_capacity(3);
tmp.insert("foo", 101);
tmp.insert("bar", 42);
tmp.insert("baz", 1969);
tmp
};
assert_eq!(left, right);
}
#[test]
fn replace_value_in_hashmap() {
let tmp = HashMap::new().apply(|m| m.insert(42, '!'));
let (left_map, inner_value) = tmp.apply_keep(|m| m.insert(42, '_'));
let right_map = HashMap::new().apply(|m| m.insert(42, '_'));
assert_eq!(left_map, right_map);
assert_eq!(inner_value, Some('!'));
}
#[test]
fn unwrap_non_panic_path() {
let tmp = HashMap::new().apply(|m| m.insert(42, '!'));
let left = tmp.apply_unwrap(|m| m.insert(42, '~'));
let right = HashMap::new().apply(|m| m.insert(42, '~'));
assert_eq!(left, right);
}
#[test]
#[should_panic]
fn unwrap_panic_path() {
let _ = Vec::<()>::new().apply_unwrap(|v| v.pop());
}
}