Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::future::Future;
- fn main() {
- let mut conn = Connection;
- conn.transaction(|conn: &mut Connection| async move {
- conn.execute("Hi").await?;
- conn.execute("Hi2").await
- });
- }
- struct Connection;
- impl Connection {
- async fn execute(&mut self, s: &str) -> Result<(), ()> {
- println!("{}", s);
- Ok(())
- }
- async fn transaction<F, T>(&mut self, f: F) -> Result<T, ()>
- where
- F: for<'a> AsyncFnOnceWithOurBounds<&'a mut Self, Output = Result<T, ()>>,
- {
- self.execute("BEGIN").await?;
- let res = f.async_call_once(self).await;
- if res.is_ok() {
- self.execute("COMMIT").await?;
- } else {
- self.execute("ROLLBACK").await?;
- }
- res
- }
- }
- trait AsyncFnOnceWithOurBounds<Args> {
- type Output;
- type Future: Future<Output = Self::Output>;
- fn async_call_once(self, args: Args) -> Self::Future;
- }
- impl<'a, F, Args, Fut> AsyncFnOnceWithOurBounds<&'a mut Args> for F
- where
- F: FnOnce(&'a mut Args) -> Fut,
- Fut: Future + 'a,
- {
- type Output = Fut::Output;
- type Future = Fut;
- fn async_call_once(self, args: &'a mut Args) -> Self::Future {
- self(args)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement