ref_wrapper 0.1.2

Wrapper of dynamically borrowed data.
Documentation
use for_test::*;
use ref_wrapper::{RefIter, RefIterMut, RefWrap, RefWrapMut};
use std::cell::RefCell;

#[test]
fn ref_wrap() {
    with_deref();
    with_deref_mut();
    with_borrow_shared();
    with_borrow_collision();

    fn with_deref() {
        let src = RefCell::new(samples());
        let result = RefWrap::new(src.borrow(), |x| Box::new(summary(x)));
        assert_eq!(*result, summary(&samples()));
    }

    fn with_deref_mut() {
        let src = RefCell::new(samples());
        let mut result = RefWrap::new(src.borrow(), |x| Box::new(summary(x)));
        *result += 1;
        assert_eq!(*result, summary(&samples()) + 1);
    }

    fn with_borrow_shared() {
        let src = RefCell::new(samples());
        let _keep_borrow = RefWrap::new(src.borrow(), |_| Box::new(()));
        assert!(src.try_borrow().is_ok());
    }

    fn with_borrow_collision() {
        let src = RefCell::new(samples());
        let _keep_borrow = RefWrap::new(src.borrow(), |_| Box::new(()));
        assert!(src.try_borrow_mut().is_err());
    }
}

#[test]
fn ref_wrap_mut() {
    with_deref();
    with_deref_mut();
    with_borrow_collision();

    fn with_deref() {
        let src = RefCell::new(samples());
        let result = RefWrapMut::new(src.borrow_mut(), |x| Box::new(VecEditer::new(x)));
        assert_eq!(result.summary(), summary(&samples()));
    }

    fn with_deref_mut() {
        let src = RefCell::new(samples());
        let mut result = RefWrapMut::new(src.borrow_mut(), |x| Box::new(VecEditer::new(x)));
        result.edit(increment_all);
        drop(result);
        let edited = src.borrow().clone();
        let expected = edit(&mut samples(), increment_all).clone();
        assert_eq!(edited, expected)
    }

    fn with_borrow_collision() {
        let src = RefCell::new(samples());
        let _keep_borrow = RefWrapMut::new(src.borrow_mut(), |_| Box::new(()));
        assert!(src.try_borrow_mut().is_err());
    }
}

#[test]
fn ref_iter() {
    with_normal();
    with_methods_on_self_sized();

    fn with_normal() {
        let src = RefCell::new(samples());
        let iter = RefIter::new(src.borrow(), |x| Box::new(x.iter()));
        assert!(iter.eq(samples().iter()));
    }

    fn with_methods_on_self_sized() {
        let src = RefCell::new(samples());
        let iter = RefIter::new(src.borrow(), |x| Box::new(x.iter()));
        assert_eq!(iter.count(), samples().len());
    }
}

#[test]
fn ref_iter_mut() {
    with_normal();
    with_methods_on_self_sized();

    fn with_normal() {
        let src = RefCell::new(samples());
        let iter = RefIterMut::new(src.borrow_mut(), |x| Box::new(x.iter_mut()));
        iter.for_each(increment);
        let edited = src.borrow().iter().cloned().collect::<Vec<_>>();
        let expected = edit(&mut samples(), increment_all).clone();
        assert_eq!(edited, expected);
    }

    fn with_methods_on_self_sized() {
        let src = RefCell::new(samples());
        let iter = RefIterMut::new(src.borrow_mut(), |x| Box::new(x.iter_mut()));
        assert_eq!(iter.count(), samples().len());
    }
}

mod for_test {
    pub fn samples() -> Vec<i32> {
        vec![1, 2, 3]
    }

    pub fn summary(vec: &Vec<i32>) -> i32 {
        vec.iter().sum::<i32>()
    }

    pub fn increment(x: &mut i32) {
        *x += 1;
    }

    pub fn increment_all(vec: &mut Vec<i32>) {
        vec.iter_mut().for_each(increment);
    }

    pub fn edit<F>(target: &mut Vec<i32>, f: F) -> &mut Vec<i32>
    where
        F: FnOnce(&mut Vec<i32>),
    {
        f(target);
        target
    }

    pub struct VecEditer<'a> {
        base: &'a mut Vec<i32>,
    }

    impl<'a> VecEditer<'a> {
        pub fn new(base: &'a mut Vec<i32>) -> Self {
            Self { base }
        }

        pub fn summary(&self) -> i32 {
            summary(self.base)
        }

        pub fn edit<F>(&mut self, f: F)
        where
            F: FnOnce(&mut Vec<i32>),
        {
            edit(&mut self.base, f);
        }
    }
}