edgedb-tokio 0.5.0

EdgeDB database client implementation for tokio.
Documentation
use std::error::Error;
use rand::{thread_rng, Rng};

use edgedb_errors::{ErrorKind, UserError};

#[derive(thiserror::Error, Debug)]
#[error("should not apply this counter update")]
struct CounterError;

fn check_val0(val: i64) -> anyhow::Result<()> {
    if val % 3 == 0 {
        if thread_rng().gen_bool(0.9) {
            return Err(CounterError)?;
        }
    }
    Ok(())
}

fn check_val1(val: i64) -> Result<(), CounterError> {
    if val % 3 == 1 {
        if thread_rng().gen_bool(0.1) {
            return Err(CounterError)?;
        }
    }
    Ok(())
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    env_logger::init();
    let conn = edgedb_tokio::create_client().await?;
    let res = conn.transaction(|mut transaction| async move {
        let val = transaction.query_required_single::<i64, _>("
                WITH counter := (UPDATE Counter SET { value := .value + 1}),
                SELECT counter.value LIMIT 1
            ", &(),
        ).await?;
        check_val0(val)?;
        check_val1(val).map_err(UserError::with_source)?;
        Ok(val)
    }).await;
    match res {
        Ok(val) => println!("New counter value: {val}"),
        Err(e) if e.source().map_or(false, |e| e.is::<CounterError>()) => {
            println!("Skipping: {e:#}");
        }
        Err(e) => return Err(e)?,
    }
    Ok(())
}