jay-compositor 1.13.0

The Jay compositor
use {
    crate::{
        sm::{
            SessionManager, SessionName,
            sm_jobs::{SmDbStateHolder, sm_common::CreateDbStateError},
        },
        sqlite::{SqliteCtx, SqliteError, SqliteJob, SqliteWork},
        utils::{errorfmt::ErrorFmt, opaque::opaque},
    },
    std::{
        rc::{Rc, Weak},
        sync::Arc,
    },
    thiserror::Error,
};

pub struct SessionDelJob {
    pub work: SessionDelWork,
    manager: Weak<SessionManager>,
}

pub struct SessionDelWork {
    pub session: SessionName,
    db_state: Arc<SmDbStateHolder>,
}

#[derive(Debug, Error)]
enum SessionDelError {
    #[error(transparent)]
    CreateDbState(#[from] CreateDbStateError),
    #[error(transparent)]
    Sqlite(#[from] SqliteError),
}

impl SessionDelJob {
    pub fn new(manager: &Rc<SessionManager>) -> Self {
        Self {
            work: SessionDelWork {
                session: SessionName(opaque()),
                db_state: manager.db_state.clone(),
            },
            manager: Rc::downgrade(manager),
        }
    }
}

impl SqliteJob for SessionDelJob {
    fn work(&mut self) -> &mut dyn SqliteWork {
        &mut self.work
    }

    fn completed(self: Box<Self>) {
        if let Some(manager) = self.manager.upgrade() {
            manager.session_del_jobs.push(self);
        }
    }
}

impl SqliteWork for SessionDelWork {
    fn run(&mut self, ctx: &mut SqliteCtx) {
        if let Err(e) = self.try_run(ctx) {
            log::error!("Delete session failed: {}", ErrorFmt(e));
        }
    }
}

impl SessionDelWork {
    fn try_run(&mut self, ctx: &mut SqliteCtx) -> Result<(), SessionDelError> {
        db_state!(s, self, ctx);
        let stmt = s.s.session_del.activate();
        stmt.bind_blob(1, self.session.0.as_bytes())?;
        stmt.bind_user_id(2, ctx.user_id)?;
        stmt.exec()?;
        Ok(())
    }
}