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
//! Ware provides mutable and immutable middleware abstractions. Basically, it means that //! you can pass one variable through a series of functions that all have the //! ability to modify this variable, therefore sending this modified version of //! it further down the chain. //! //! Ware is used like this: //! //! ``` //! use ware::Ware; //! use std::ops::{Mul, Sub}; //! //! fn main() { //! let mut chain: Ware<i32> = Ware::new(); //! chain.wrap(Box::new(|mut num| { //! *num = num.mul(5); //! })); //! chain.wrap(Box::new(|mut num| { //! *num = num.sub(2); //! })); //! let result = chain.run(5); //! assert_eq!(result, 23); //! } //! ``` use std::cell::{RefCell, RefMut}; pub mod im; /// Shorthand version of `RefMut<T>`, if you don't want to import `RefMut`. pub type WareArg<'a, T> = RefMut<'a, T>; /// A middleware chain. pub struct Ware<T> { /// The internal list of middleware functions. pub fns: Vec<Box<dyn Fn(WareArg<T>) -> ()>>, } impl<T> Ware<T> { /// Create a new middleware chain with a given type. /// /// # Example /// ``` /// use ware::Ware; /// let mut chain: Ware<String> = Ware::new(); /// ``` pub fn new() -> Ware<T> { let vec: Vec<Box<dyn Fn(WareArg<T>) -> ()>> = Vec::new(); Ware { fns: vec } } /// Add a new middleware function to the internal function list. This function /// must be of the `Fn` trait, take a `WareArg<T>` and return a unit struct (aka. nothing). /// It also has to be boxed for memory safety reasons. /// /// # Example /// ``` /// use ware::Ware; /// let mut chain: Ware<String> = Ware::new(); /// chain.wrap(Box::new(|mut st| { /// st.push('a'); /// })) /// ``` pub fn wrap(&mut self, func: Box<dyn Fn(WareArg<T>) -> ()>) { self.fns.push(func); } /// Run the registered middleware functions with the given value to pass /// through. Returns whatever the passed value will be after the last /// middleware function runs. pub fn run(&self, arg: T) -> T { let ware_arg = RefCell::new(arg); self.fns.iter().for_each(|func| func(ware_arg.borrow_mut())); ware_arg.into_inner() } } #[cfg(test)] mod tests { use std::ops::Add; use super::*; #[test] fn it_works() { let value = 1; let mut w: Ware<i32> = Ware::new(); w.wrap(Box::new(|mut num| { *num = num.add(1); })); assert_eq!(w.run(value), 2); } }