From 7806c473b1260bc64b4bd81467093262c1666187 Mon Sep 17 00:00:00 2001 From: Adrien Burgun Date: Fri, 8 Jul 2022 19:05:04 +0200 Subject: [PATCH] :sparkles: VecRef::try_map and VecRefMut::try_map --- Cargo.toml | 2 +- src/test.rs | 25 +++++++++++++++++++++++++ src/vecref.rs | 11 +++++++++++ src/vecrefmut.rs | 15 +++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c73e478..ea7f3e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "veccell" -version = "0.2.0" +version = "0.2.1" edition = "2021" authors = [ "Shad Amethyst " ] description = "Provides VecCell, a variant of Vec with interior mutability." diff --git a/src/test.rs b/src/test.rs index cb220d5..e38b8c8 100644 --- a/src/test.rs +++ b/src/test.rs @@ -271,3 +271,28 @@ fn test_range() { std::mem::drop(elem); } + +#[test] +fn test_try_map() { + let mut vec: VecCell> = VecCell::new(); + + for x in -10..10 { + vec.push(Box::new(x)); + } + + let ref_mut = vec.borrow_mut(5).unwrap(); + assert!(VecRefMut::try_map(ref_mut, |_value| Err::<&mut (), ()>(())).is_err()); + + let ref_mut = vec.borrow_mut(5).unwrap(); + let ref_mut: Result, ()> = VecRefMut::try_map(ref_mut, |value| Ok(value.as_mut())); + assert!(ref_mut.is_ok()); + assert_eq!(ref_mut.unwrap(), -5); + + let borrow = vec.borrow(6).unwrap(); + assert!(VecRef::try_map(borrow, |_value| Err::<&(), ()>(())).is_err()); + + let borrow = vec.borrow(4).unwrap(); + let borrow: Result, ()> = VecRef::try_map(borrow, |value| Ok(value.as_ref())); + assert!(borrow.is_ok()); + assert_eq!(borrow.unwrap(), -6); +} diff --git a/src/vecref.rs b/src/vecref.rs index 5d029da..5c6ccaa 100644 --- a/src/vecref.rs +++ b/src/vecref.rs @@ -99,6 +99,17 @@ impl<'a, T: ?Sized> VecRef<'a, T> { VecRef::from(f(original.value), original.borrows.clone()) // original is dropped here } + + /// Variant of [`VecRef::map`], where the callback (`f`) may fail. + /// + /// `f` must return a `Result`; if it returns `Ok(x)`, then `try_map` returns `Ok(VecRef(x))`. + /// Otherwise, it returns `Err(err)`. + pub fn try_map<'b, U: ?Sized, F, E>(original: VecRef<'b, T>, f: F) -> Result, E> + where + F: FnOnce(&T) -> Result<&U, E> + { + Ok(VecRef::from(f(original.value)?, original.borrows.clone())) + } } impl<'a, T: ?Sized> Deref for VecRef<'a, T> { diff --git a/src/vecrefmut.rs b/src/vecrefmut.rs index 5619c40..7c41795 100644 --- a/src/vecrefmut.rs +++ b/src/vecrefmut.rs @@ -103,6 +103,21 @@ impl<'a, T: ?Sized> VecRefMut<'a, T> { mut_borrow } } + + /// Variant of [`VecRefMut::map`], where the callback (`f`) may fail. + /// + /// `f` must return a `Result`; if it returns `Ok(x)`, then `try_map` returns `Ok(VecRefMut(x))`. + /// Otherwise, it returns `Err(err)`. + pub fn try_map<'b, U: ?Sized, F, E>(original: VecRefMut<'b, T>, f: F) -> Result, E> + where + F: FnOnce(&mut T) -> Result<&mut U, E> + { + let VecRefMut { value, mut_borrow } = original; + Ok(VecRefMut { + value: f(value)?, + mut_borrow: mut_borrow + }) + } } impl<'a, T: ?Sized> Deref for VecRefMut<'a, T> {