Skip to content

Commit

Permalink
CollectionDocument::modify allows returning values
Browse files Browse the repository at this point in the history
Closes #312
  • Loading branch information
ecton committed Dec 4, 2023
1 parent 1ba4613 commit 5f14c11
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Breaking Changes

- `CollectionDocument::modify`/`CollectionDocument::modify_async` now take an
additional parameter: the return type of the callback function. This result
from the call that succeeds in updating will be returned in `Ok`.

### Added

- `bonsaidb::client::Error` now implements
Expand Down
24 changes: 16 additions & 8 deletions crates/bonsaidb-core/src/document/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,20 @@ where
/// Modifies `self`, automatically retrying the modification if the document
/// has been updated on the server.
///
/// The contents of `Ok` will be the last value returned from `modifier`.
///
/// ## Data loss warning
///
/// If you've modified `self` before calling this function and a conflict
/// occurs, all changes to self will be lost when the current document is
/// fetched before retrying the process again. When you use this function,
/// you should limit the edits to the value to within the `modifier`
/// callback.
pub fn modify<Cn: Connection, Modifier: FnMut(&mut Self) + Send + Sync>(
pub fn modify<R, Cn: Connection, Modifier: FnMut(&mut Self) -> R + Send + Sync>(
&mut self,
connection: &Cn,
mut modifier: Modifier,
) -> Result<(), Error>
) -> Result<R, Error>
where
C::Contents: Clone,
{
Expand All @@ -176,29 +178,35 @@ where
}
})?;
}
modifier(&mut *self);
let result = modifier(&mut *self);
match self.update(connection) {
Err(Error::DocumentConflict(..)) => {}
other => return other,
other => return other.map(|()| result),
}
}
}

/// Modifies `self`, automatically retrying the modification if the document
/// has been updated on the server.
///
/// The contents of `Ok` will be the last value returned from `modifier`.
///
/// ## Data loss warning
///
/// If you've modified `self` before calling this function and a conflict
/// occurs, all changes to self will be lost when the current document is
/// fetched before retrying the process again. When you use this function,
/// you should limit the edits to the value to within the `modifier`
/// callback.
pub async fn modify_async<Cn: AsyncConnection, Modifier: FnMut(&mut Self) + Send + Sync>(
pub async fn modify_async<
R,
Cn: AsyncConnection,
Modifier: FnMut(&mut Self) -> R + Send + Sync,
>(
&mut self,
connection: &Cn,
mut modifier: Modifier,
) -> Result<(), Error>
) -> Result<R, Error>
where
C::Contents: Clone,
{
Expand All @@ -218,10 +226,10 @@ where
Err(err) => err,
})?;
}
modifier(&mut *self);
let result = modifier(&mut *self);
match self.update_async(connection).await {
Err(Error::DocumentConflict(..)) => {}
other => return other,
other => return other.map(|()| result),
}
}
}
Expand Down

0 comments on commit 5f14c11

Please sign in to comment.