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

//! You can use it to allow extending method chain.
//!
//!
//!
//!
//! # Examples (Extendable builder with future-proof)
//!
//! ```rust
//! // mock
//! mod othercrate {
//! 	use mutator::Mutator;
//! 	pub struct CrateBuilder {
//! 		pool_size: usize,
//! 	}
//!
//! 	impl CrateBuilder {
//! 		// not important in this example
//! 		pub fn build(self) -> () {
//! 		}
//! 	}
//!
//! 	pub trait CrateBuilderMut: Mutator<CrateBuilder> {
//! 		// returns self, so it can be builder type of wrapper library
//! 		//
//! 		fn with_pool_size(self, pool_size: usize) -> Self {
//! 			self.mutate(|b| b.pool_size = pool_size)
//! 		}
//! 	}
//!
//!
//! 	/// Mutator<CrateBuilder> is implemented for CrateBuilder, as logically it is.
//! 	///
//!  	/// Any type which can mutate CrateBuilder can be used as CrateBuilder.
//! 	///
//! 	impl<B> CrateBuilderMut for B where B: Mutator<CrateBuilder> {}
//!
//! 	pub fn builder() -> CrateBuilder {
//! 		CrateBuilder{ pool_size: 0 }
//! 	}
//! }
//!
//!
//! // mock wrapper crate
//! mod runner {
//! 	use mutator::Mutator;
//! 	use othercrate::{self, CrateBuilder};
//! 	pub use othercrate::CrateBuilderMut;
//!
//! 	pub struct RunnerBuilder {
//! 		name: Option<&'static str>,
//! 		crate_builder: CrateBuilder,
//! 	}
//!
//! 	impl RunnerBuilder {
//! 		/// not important in this example
//! 		pub fn build(self) -> () {
//! 		}
//! 	}
//!
//!
//! 	pub trait RunnerBuilderMut: Mutator<RunnerBuilder> {
//! 		fn with_name(self, name: &'static str) -> Self {
//! 			self.mutate(|b| b.name = Some(name))
//! 		}
//! 	}
//!
//! 	impl<B> RunnerBuilderMut for B where B: Mutator<RunnerBuilder> {}
//!
//! 	/// By this, methods on CrateBuilder can be called on RunnerBuilder
//! 	impl Mutator<CrateBuilder> for RunnerBuilder {
//! 		fn mutate<F>(mut self, op: F) -> Self where F: FnOnce(&mut CrateBuilder) {
//! 			op(&mut self.crate_builder);
//! 			self
//! 		}
//! 	}
//!
//!
//! 	pub fn new() -> RunnerBuilder {
//! 		RunnerBuilder {
//! 			name: None,
//! 			crate_builder: othercrate::builder(),
//! 		}
//! 	}
//! }
//!
//!
//!
//! // end-user
//!
//! use runner::{RunnerBuilderMut, CrateBuilderMut};
//!
//! fn main() {
//! 	let _ = runner::new().with_pool_size(10).with_name("whoami").build();
//!
//! }
//! ```


/// **Mutator<T>** is a type which can mutate T.
///
/// Any type implements Mutator<Self> as logically it is.
pub trait Mutator<T>: Sized {
    fn mutate<F>(self, op: F) -> Self where F: FnOnce(&mut T);
}

impl<T> Mutator<T> for T {
    fn mutate<F>(mut self, op: F) -> Self
        where F: FnOnce(&mut T)
    {
        op(&mut self);
        self
    }
}