1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/// Enables immutable call chaining on all types.
///
/// # Example
///
/// ```rust
/// use chainer::*;
///
/// struct HelloWorld;
/// impl HelloWorld {
///     fn print(&self) {
///         println!("Hello, world!");
///     }
/// }
///
/// fn main() {
///     HelloWorld
///         .chain(HelloWorld::print)
///         .chain(HelloWorld::print)
///         .chain(HelloWorld::print);
///
///     // Hello, world!
///     // Hello, world!
///     // Hello, world!
/// }
/// ```
pub trait CallChain {
	/// Enables immutable call chaining on all types.
	///
	/// # Example
	///
	/// ```rust
	/// use chainer::*;
	///
	/// struct HelloWorld;
	/// impl HelloWorld {
	///     fn print(&self) {
	///         println!("Hello, world!");
	///     }
	/// }
	///
	/// fn main() {
	///     HelloWorld
	///         .chain(HelloWorld::print)
	///         .chain(HelloWorld::print)
	///         .chain(HelloWorld::print);
	///
	///     // Hello, world!
	///     // Hello, world!
	///     // Hello, world!
	/// }
	/// ```
	fn chain<R, F: FnOnce(&Self) -> R>(&self, f: F) -> &Self {
		f(self);
		self
	}
}

/// Enables mutable call chaining on all types.
///
/// # Example
///
/// ```rust
/// use chainer::*;
///
/// struct Counter { value: i32 }
/// impl Counter {
///     fn increment(&mut self) {
///         self.value += 1;
///         println!("{}", self.value);
///     }
/// }
///
/// fn main() {
///     Counter { value: 0 }
///         .chain_mut(Counter::increment)
///         .chain_mut(Counter::increment)
///         .chain_mut(Counter::increment);
///
///     // 1
///     // 2
///     // 3
/// }
/// ```
pub trait CallChainMut {
	/// Enables mutable call chaining on all types.
	///
	/// # Example
	///
	/// ```rust
	/// use chainer::*;
	///
	/// struct Counter { value: i32 }
	/// impl Counter {
	///     fn increment(&mut self) {
	///         self.value += 1;
	///         println!("{}", self.value);
	///     }
	/// }
	///
	/// fn main() {
	///     Counter { value: 0 }
	///         .chain_mut(Counter::increment)
	///         .chain_mut(Counter::increment)
	///         .chain_mut(Counter::increment);
	///
	///     // 1
	///     // 2
	///     // 3
	/// }
	/// ```
	fn chain_mut<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> &mut Self {
		f(self);
		self
	}
}

impl<T: ?Sized> CallChain for T {}
impl<T: ?Sized> CallChainMut for T {}