text-document-editing 1.4.2

Undoable text editing use cases for text-document
Documentation
// Generated by Qleany v1.4.8 from feature_use_case_uow.tera

use crate::use_cases::insert_html_at_position_uc::{
    InsertHtmlAtPositionUnitOfWorkFactoryTrait, InsertHtmlAtPositionUnitOfWorkTrait,
};
use anyhow::{Ok, Result};
use common::database::CommandUnitOfWork;
use common::database::{db_context::DbContext, transactions::Transaction};
#[allow(unused_imports)]
use common::entities::{Block, Document, Frame, InlineElement, List, Root};
use common::event::{AllEvent, DirectAccessEntity, Event, EventBuffer, EventHub, Origin};
#[allow(unused_imports)]
use common::types;
#[allow(unused_imports)]
use common::types::EntityId;
use std::cell::RefCell;
use std::sync::Arc;

// Unit of work for InsertHtmlAtPosition

pub struct InsertHtmlAtPositionUnitOfWork {
    context: DbContext,
    transaction: Option<Transaction>,
    event_hub: Arc<EventHub>,
    event_buffer: RefCell<EventBuffer>,
}

impl InsertHtmlAtPositionUnitOfWork {
    pub fn new(db_context: &DbContext, event_hub: &Arc<EventHub>) -> Self {
        InsertHtmlAtPositionUnitOfWork {
            context: db_context.clone(),
            transaction: None,
            event_hub: event_hub.clone(),
            event_buffer: RefCell::new(EventBuffer::new()),
        }
    }
}

impl CommandUnitOfWork for InsertHtmlAtPositionUnitOfWork {
    fn begin_transaction(&mut self) -> Result<()> {
        self.transaction = Some(Transaction::begin_write_transaction(&self.context)?);
        self.event_buffer.get_mut().begin_buffering();
        Ok(())
    }

    fn commit(&mut self) -> Result<()> {
        self.transaction.take().unwrap().commit()?;
        for event in self.event_buffer.get_mut().flush() {
            self.event_hub.send_event(event);
        }
        Ok(())
    }

    fn rollback(&mut self) -> Result<()> {
        self.transaction.take().unwrap().rollback()?;
        self.event_buffer.get_mut().discard();
        Ok(())
    }

    fn create_savepoint(&self) -> Result<types::Savepoint> {
        self.transaction.as_ref().unwrap().create_savepoint()
    }

    fn restore_to_savepoint(&mut self, savepoint: types::Savepoint) -> Result<()> {
        let mut transaction = self.transaction.take().unwrap();
        transaction.restore_to_savepoint(savepoint)?;

        // Discard buffered events — savepoint restore invalidated them
        self.event_buffer.get_mut().discard();

        // Send Reset immediately (not buffered — UI must refresh now)
        self.event_hub.send_event(Event {
            origin: Origin::DirectAccess(DirectAccessEntity::All(AllEvent::Reset)),
            ids: vec![],
            data: None,
        });

        // Recreate the transaction after restoring to savepoint
        self.transaction = Some(transaction);

        Ok(())
    }
}

//TODO: adapt entities and actions to real use :
// Create, CreateMulti, Get, GetMulti, Update (scalar-only), UpdateMulti (scalar-only),
// UpdateWithRelationships, UpdateWithRelationshipsMulti,
// Remove, RemoveMulti, GetRelationship,
// GetRelationshipsFromRightIds, SetRelationship, SetRelationshipMulti, Snapshot, Restore
//
// You have here a read-write unit of work.
//
// RO means Read Only, so *RO actions should not used be here.
// Don't forget to set thread_safe = true for long operation's unit of work.
// Do not mix read-only and write actions in the same unit of work.
//
// Exactly the same macros must be set in the use case uow trait file in ../use_cases/insert_html_at_position_uc.rs
//
#[macros::uow_action(entity = "Root", action = "Get")]
#[macros::uow_action(entity = "Root", action = "GetRelationship")]
#[macros::uow_action(entity = "Document", action = "Get")]
#[macros::uow_action(entity = "Document", action = "Update")]
#[macros::uow_action(entity = "Document", action = "GetRelationship")]
#[macros::uow_action(entity = "Document", action = "Snapshot")]
#[macros::uow_action(entity = "Document", action = "Restore")]
#[macros::uow_action(entity = "Frame", action = "Get")]
#[macros::uow_action(entity = "Frame", action = "Update")]
#[macros::uow_action(entity = "Frame", action = "GetRelationship")]
#[macros::uow_action(entity = "Block", action = "Get")]
#[macros::uow_action(entity = "Block", action = "GetMulti")]
#[macros::uow_action(entity = "Block", action = "Update")]
#[macros::uow_action(entity = "Block", action = "UpdateMulti")]
#[macros::uow_action(entity = "Block", action = "Create")]
#[macros::uow_action(entity = "Block", action = "GetRelationship")]
#[macros::uow_action(entity = "Block", action = "UpdateWithRelationships")]
#[macros::uow_action(entity = "InlineElement", action = "Get")]
#[macros::uow_action(entity = "InlineElement", action = "GetMulti")]
#[macros::uow_action(entity = "InlineElement", action = "Update")]
#[macros::uow_action(entity = "InlineElement", action = "Create")]
#[macros::uow_action(entity = "InlineElement", action = "Remove")]
#[macros::uow_action(entity = "List", action = "Get")]
#[macros::uow_action(entity = "List", action = "Create")]
impl InsertHtmlAtPositionUnitOfWorkTrait for InsertHtmlAtPositionUnitOfWork {}

pub struct InsertHtmlAtPositionUnitOfWorkFactory {
    context: DbContext,
    event_hub: Arc<EventHub>,
}

impl InsertHtmlAtPositionUnitOfWorkFactory {
    pub fn new(db_context: &DbContext, event_hub: &Arc<EventHub>) -> Self {
        InsertHtmlAtPositionUnitOfWorkFactory {
            context: db_context.clone(),
            event_hub: event_hub.clone(),
        }
    }
}

impl InsertHtmlAtPositionUnitOfWorkFactoryTrait for InsertHtmlAtPositionUnitOfWorkFactory {
    fn create(&self) -> Box<dyn InsertHtmlAtPositionUnitOfWorkTrait> {
        Box::new(InsertHtmlAtPositionUnitOfWork::new(
            &self.context,
            &self.event_hub,
        ))
    }
}