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_set_relationship.tera

use super::traits::WriteRelUoWFactory;
use crate::types::{EntityId, Savepoint};
use crate::undo_redo::UndoRedoCommand;
use anyhow::Result;
use std::any::Any;
use std::collections::VecDeque;

// ---------------------------------------------------------------------------
// Non-undoable set-relationship
// ---------------------------------------------------------------------------

pub struct SetRelationshipUseCase<RF, F: WriteRelUoWFactory<RF>> {
    uow_factory: F,
    _phantom: std::marker::PhantomData<RF>,
}

impl<RF, F: WriteRelUoWFactory<RF>> SetRelationshipUseCase<RF, F> {
    pub fn new(uow_factory: F) -> Self {
        SetRelationshipUseCase {
            uow_factory,
            _phantom: std::marker::PhantomData,
        }
    }

    pub fn execute(&mut self, id: &EntityId, field: &RF, right_ids: &[EntityId]) -> Result<()> {
        let mut uow = self.uow_factory.create();
        uow.begin_transaction()?;
        uow.set_relationship(id, field, right_ids)?;
        uow.commit()?;
        Ok(())
    }
}

// ---------------------------------------------------------------------------
// Undoable set-relationship
// ---------------------------------------------------------------------------

pub struct UndoableSetRelationshipUseCase<RF: Clone, F: WriteRelUoWFactory<RF>> {
    uow_factory: F,
    undo_stack: VecDeque<Savepoint>,
    redo_stack: VecDeque<(EntityId, RF, Vec<EntityId>)>,
}

impl<RF: Clone, F: WriteRelUoWFactory<RF>> UndoableSetRelationshipUseCase<RF, F> {
    pub fn new(uow_factory: F) -> Self {
        UndoableSetRelationshipUseCase {
            uow_factory,
            undo_stack: VecDeque::new(),
            redo_stack: VecDeque::new(),
        }
    }

    pub fn execute(&mut self, id: &EntityId, field: &RF, right_ids: &[EntityId]) -> Result<()> {
        let mut uow = self.uow_factory.create();
        uow.begin_transaction()?;
        let savepoint = uow.create_savepoint()?;
        uow.set_relationship(id, field, right_ids)?;
        uow.commit()?;
        self.undo_stack.push_back(savepoint);
        self.redo_stack
            .push_back((*id, field.clone(), right_ids.to_vec()));
        Ok(())
    }
}

impl<RF: Clone + Send + 'static, F: WriteRelUoWFactory<RF> + Send + 'static> UndoRedoCommand
    for UndoableSetRelationshipUseCase<RF, F>
{
    fn undo(&mut self) -> Result<()> {
        if let Some(savepoint) = self.undo_stack.pop_back() {
            let mut uow = self.uow_factory.create();
            uow.begin_transaction()?;
            uow.restore_to_savepoint(savepoint)?;
            uow.commit()?;
        }
        Ok(())
    }

    fn redo(&mut self) -> Result<()> {
        if let Some((id, field, right_ids)) = self.redo_stack.pop_back() {
            let mut uow = self.uow_factory.create();
            uow.begin_transaction()?;
            let savepoint = uow.create_savepoint()?;
            uow.set_relationship(&id, &field, &right_ids)?;
            uow.commit()?;
            self.undo_stack.push_back(savepoint);
        }
        Ok(())
    }

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