diff options
author | Vika <vika@fireburn.ru> | 2024-08-28 15:01:57 +0300 |
---|---|---|
committer | Vika <vika@fireburn.ru> | 2024-08-28 15:04:17 +0300 |
commit | 4f1fe5404c954c85f3bc2379c7ae130b57ea5e73 (patch) | |
tree | 9b36f884ce23849ac9fd1ebd03d1e394d05b976c /src/database/mod.rs | |
parent | e03ff3151878851af954aa2e9a17e7578873bbae (diff) | |
download | kittybox-4f1fe5404c954c85f3bc2379c7ae130b57ea5e73.tar.zst |
Introduce `Storage::update_with`
This function takes a closure that modifies the post. This could be useful in maintenance utilities that scan and fixup posts. For now this isn't used anywhere within Kittybox, but once all backends implement this correctly, this could replace `Storage::update_post` calls. For supporting backends, `Storage::update_post` is implemented in terms of `Storage::update_with`.
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. |