text-document-common 1.4.0

Shared entities, database, events, and undo/redo infrastructure for text-document
Documentation
// Generated by Qleany v1.4.8 from common_da_use_cases_remove.tera

use super::traits::WriteUoWFactory;
use crate::snapshot::EntityTreeSnapshot;
use crate::types::EntityId;
use crate::undo_redo::UndoRedoCommand;
use anyhow::{Ok, Result};
use std::any::Any;

// ---------------------------------------------------------------------------
// Non-undoable remove
// ---------------------------------------------------------------------------

pub struct RemoveUseCase<F: WriteUoWFactory> {
    uow_factory: F,
}

impl<F: WriteUoWFactory> RemoveUseCase<F> {
    pub fn new(uow_factory: F) -> Self {
        RemoveUseCase { uow_factory }
    }

    pub fn execute(&mut self, id: &EntityId) -> Result<()> {
        self.execute_multi(&[*id])
    }

    pub fn execute_multi(&mut self, ids: &[EntityId]) -> Result<()> {
        let mut uow = self.uow_factory.create();
        uow.begin_transaction()?;
        for id in ids {
            if uow.get(id)?.is_none() {
                return Err(anyhow::anyhow!("Entity with id {} does not exist", id));
            }
        }
        uow.remove_multi(ids)?;
        uow.commit()?;
        Ok(())
    }
}

// ---------------------------------------------------------------------------
// Undoable remove
// ---------------------------------------------------------------------------

pub struct UndoableRemoveUseCase<F: WriteUoWFactory> {
    uow_factory: F,
    entity_tree_snapshot: Option<EntityTreeSnapshot>,
    original_ids: Option<Vec<EntityId>>,
}

impl<F: WriteUoWFactory> UndoableRemoveUseCase<F> {
    pub fn new(uow_factory: F) -> Self {
        UndoableRemoveUseCase {
            uow_factory,
            entity_tree_snapshot: None,
            original_ids: None,
        }
    }

    pub fn execute(&mut self, id: &EntityId) -> Result<()> {
        self.execute_multi(&[*id])
    }

    pub fn execute_multi(&mut self, ids: &[EntityId]) -> Result<()> {
        let mut uow = self.uow_factory.create();
        uow.begin_transaction()?;
        for id in ids {
            if uow.get(id)?.is_none() {
                return Err(anyhow::anyhow!("Entity with id {} does not exist", id));
            }
        }
        self.entity_tree_snapshot = Some(uow.snapshot(ids)?);
        uow.remove_multi(ids)?;
        uow.commit()?;
        self.original_ids = Some(ids.to_vec());
        Ok(())
    }
}

impl<F: WriteUoWFactory + Send + 'static> UndoRedoCommand for UndoableRemoveUseCase<F>
where
    F::Entity: 'static,
{
    fn undo(&mut self) -> Result<()> {
        if let Some(ref snap) = self.entity_tree_snapshot {
            let mut uow = self.uow_factory.create();
            uow.begin_transaction()?;
            uow.restore(snap)?;
            uow.commit()?;
        }
        Ok(())
    }

    fn redo(&mut self) -> Result<()> {
        if let Some(ref ids) = self.original_ids {
            let mut uow = self.uow_factory.create();
            uow.begin_transaction()?;
            self.entity_tree_snapshot = Some(uow.snapshot(ids)?);
            uow.remove_multi(ids)?;
            uow.commit()?;
        }
        Ok(())
    }

    fn as_any(&self) -> &dyn Any {
        self
    }
}