Skip to main content

common/direct_access/use_cases/
move_relationship.rs

1// Generated by Qleany v1.11.0 from common_da_use_cases_move_relationship.tera
2
3use super::traits::WriteRelUoWFactory;
4use crate::types::EntityId;
5use crate::undo_redo::UndoRedoCommand;
6use anyhow::Result;
7use std::any::Any;
8use std::collections::VecDeque;
9
10// ---------------------------------------------------------------------------
11// Non-undoable move-relationship
12// ---------------------------------------------------------------------------
13
14pub struct MoveRelationshipUseCase<RF, F: WriteRelUoWFactory<RF>> {
15    uow_factory: F,
16    _phantom: std::marker::PhantomData<RF>,
17}
18
19impl<RF, F: WriteRelUoWFactory<RF>> MoveRelationshipUseCase<RF, F> {
20    pub fn new(uow_factory: F) -> Self {
21        MoveRelationshipUseCase {
22            uow_factory,
23            _phantom: std::marker::PhantomData,
24        }
25    }
26
27    pub fn execute(
28        &mut self,
29        id: &EntityId,
30        field: &RF,
31        ids_to_move: &[EntityId],
32        new_index: i32,
33    ) -> Result<Vec<EntityId>> {
34        let mut uow = self.uow_factory.create();
35        uow.begin_transaction()?;
36        let result = uow.move_relationship(id, field, ids_to_move, new_index)?;
37        uow.commit()?;
38        Ok(result)
39    }
40}
41
42// ---------------------------------------------------------------------------
43// Undoable move-relationship
44// ---------------------------------------------------------------------------
45
46pub struct UndoableMoveRelationshipUseCase<RF: Clone, F: WriteRelUoWFactory<RF>> {
47    uow_factory: F,
48    // Scoped inverse: (id, field, before_order) restored on undo. A move is a pure reorder of one
49    // junction row, so restoring its prior order is the exact inverse — and touches nothing else.
50    undo_stack: VecDeque<(EntityId, RF, Vec<EntityId>)>,
51    redo_stack: VecDeque<(EntityId, RF, Vec<EntityId>, i32)>,
52}
53
54impl<RF: Clone, F: WriteRelUoWFactory<RF>> UndoableMoveRelationshipUseCase<RF, F> {
55    pub fn new(uow_factory: F) -> Self {
56        UndoableMoveRelationshipUseCase {
57            uow_factory,
58            undo_stack: VecDeque::new(),
59            redo_stack: VecDeque::new(),
60        }
61    }
62
63    pub fn execute(
64        &mut self,
65        id: &EntityId,
66        field: &RF,
67        ids_to_move: &[EntityId],
68        new_index: i32,
69    ) -> Result<Vec<EntityId>> {
70        let mut uow = self.uow_factory.create();
71        uow.begin_transaction()?;
72        let before = uow.get_relationship(id, field)?;
73        let result = uow.move_relationship(id, field, ids_to_move, new_index)?;
74        uow.commit()?;
75        self.undo_stack.push_back((*id, field.clone(), before));
76        self.redo_stack
77            .push_back((*id, field.clone(), ids_to_move.to_vec(), new_index));
78        Ok(result)
79    }
80}
81
82impl<RF: Clone + Send + 'static, F: WriteRelUoWFactory<RF> + Send + 'static> UndoRedoCommand
83    for UndoableMoveRelationshipUseCase<RF, F>
84{
85    fn undo(&mut self) -> Result<()> {
86        if let Some((id, field, before)) = self.undo_stack.pop_back() {
87            let mut uow = self.uow_factory.create();
88            uow.begin_transaction()?;
89            uow.set_relationship(&id, &field, &before)?;
90            uow.commit()?;
91        }
92        Ok(())
93    }
94
95    fn redo(&mut self) -> Result<()> {
96        if let Some((id, field, ids_to_move, new_index)) = self.redo_stack.pop_back() {
97            let mut uow = self.uow_factory.create();
98            uow.begin_transaction()?;
99            let before = uow.get_relationship(&id, &field)?;
100            uow.move_relationship(&id, &field, &ids_to_move, new_index)?;
101            uow.commit()?;
102            self.undo_stack.push_back((id, field, before));
103        }
104        Ok(())
105    }
106
107    fn as_any(&self) -> &dyn Any {
108        self
109    }
110}