diff --git a/Cargo.lock b/Cargo.lock index e18efc4..2e56fd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "identified_vec" -version = "0.1.9" +version = "0.1.10" dependencies = [ "identified_vec", "serde", diff --git a/Cargo.toml b/Cargo.toml index 6c7235a..387217a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "identified_vec" -version = "0.1.9" +version = "0.1.10" edition = "2021" authors = ["Alexander Cyon "] description = "Like HashSet but retaining INSERTION order and without `Hash` requirement on the Element type." diff --git a/src/vec/identified_vec.rs b/src/vec/identified_vec.rs index 43f2eab..99a6055 100644 --- a/src/vec/identified_vec.rs +++ b/src/vec/identified_vec.rs @@ -486,6 +486,22 @@ where true } + #[allow(unused_mut)] + #[inline] + fn try_update_with(&mut self, id: &I, mut mutate: F) -> Result + where + F: FnMut(E) -> Result, + { + if !self.contains_id(id) { + return Ok(false); + } + let mut existing = self.elements.remove(id).expect("Element for existing id"); + mutate(existing).map(|updated| { + self.elements.insert(id.clone(), updated); + true + }) + } + /// Try to update the given element to the `identified_vec` if a element with the same ID is already present. /// /// - Parameter item: The value to append or replace. diff --git a/src/vec/is_identified_vec.rs b/src/vec/is_identified_vec.rs index b8db0ff..042c63c 100644 --- a/src/vec/is_identified_vec.rs +++ b/src/vec/is_identified_vec.rs @@ -145,6 +145,10 @@ where where F: FnMut(&mut Element); + fn try_update_with(&mut self, id: &ID, mutate: F) -> Result + where + F: FnMut(Element) -> Result; + /// Insert a new member to this identified_vec at the specified index, if the identified_vec doesn't already contain /// it. /// diff --git a/src/vec_of/is_identified_vec_of_via.rs b/src/vec_of/is_identified_vec_of_via.rs index e030424..af80a04 100644 --- a/src/vec_of/is_identified_vec_of_via.rs +++ b/src/vec_of/is_identified_vec_of_via.rs @@ -178,6 +178,19 @@ where self.via_mut().update_with(id, mutate) } + #[allow(unused_mut)] + #[inline] + fn try_update_with( + &mut self, + id: &::ID, + mut mutate: F, + ) -> Result + where + F: FnMut(Element) -> Result, + { + self.via_mut().try_update_with(id, mutate) + } + #[inline] fn try_append_new(&mut self, element: Element) -> Result<(bool, usize), Error> { self.via_mut().try_append_new(element) diff --git a/tests/tests.rs b/tests/tests.rs index 5479ce6..b09f25d 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -404,6 +404,36 @@ fn update_with() { assert_eq!(sut.update_with(&999, |_| panic!("not called")), false); } +#[test] +fn try_update_with_contains() { + let mut sut = Users::new(); + sut.append(User::new(2, "Blob, Jr.")); + assert_eq!( + sut.try_update_with(&2, |x| { + let mut y = x; + *y.name.get_mut() = "Junior, Jr.".to_string(); + Result::::Ok(y) + }), + Ok(true) + ); + assert_eq!(sut.items(), [User::new(2, "Junior, Jr.")]); +} + +#[test] +fn try_update_with_not_contains() { + let mut sut = Users::new(); + sut.append(User::new(2, "Blob, Jr.")); + assert_eq!( + sut.try_update_with(&999, |x| { + let mut y = x; + *y.name.get_mut() = "Will never happen.".to_string(); + Result::::Ok(y) + }), + Ok(false) + ); + assert_eq!(sut.items(), [User::new(2, "Blob, Jr.")]); +} + #[test] #[should_panic(expected = "Expected element at index {index}")] fn update_at_expect_panic_unknown_index() {