diff options
Diffstat (limited to 'src/database/mod.rs')
-rw-r--r-- | src/database/mod.rs | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/database/mod.rs b/src/database/mod.rs index 058fc0c..0993715 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -251,7 +251,31 @@ pub trait Storage: std::fmt::Debug + Clone + Send + Sync { /// each other's changes or simply corrupting something. Rejecting /// is allowed in case of concurrent updates if waiting for a lock /// cannot be done. - fn update_post(&self, url: &str, update: MicropubUpdate) -> impl Future<Output = Result<()>> + Send; + /// + /// Default implementation calls [`Storage::update_with`] and uses + /// [`update.apply`][MicropubUpdate::apply] to update the post. + fn update_post(&self, url: &str, update: MicropubUpdate) -> impl Future<Output = Result<()>> + Send { + let fut = self.update_with(url, |post| { + update.apply(post); + }); + + // The old interface didn't return anything, the new interface + // returns the old and new post. Adapt accordingly. + futures::TryFutureExt::map_ok(fut, |(_old, _new)| ()) + } + + /// Modify a post using an arbitrary closure. + /// + /// Note to implementors: the update operation MUST be atomic and + /// SHOULD lock the database to prevent two clients overwriting + /// each other's changes or simply corrupting something. Rejecting + /// is allowed in case of concurrent updates if waiting for a lock + /// cannot be done. + /// + /// Returns old post and the new post after editing. + fn update_with<F: FnOnce(&mut serde_json::Value) + Send>( + &self, url: &str, f: F + ) -> impl Future<Output = Result<(serde_json::Value, serde_json::Value)>> + Send; /// Get a list of channels available for the user represented by /// the `user` domain to write to. |