text_document_common/direct_access/use_cases/
move_relationship.rs1use super::traits::WriteRelUoWFactory;
4use crate::types::{EntityId, Savepoint};
5use crate::undo_redo::UndoRedoCommand;
6use anyhow::Result;
7use std::any::Any;
8use std::collections::VecDeque;
9
10pub 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
42pub struct UndoableMoveRelationshipUseCase<RF: Clone, F: WriteRelUoWFactory<RF>> {
47 uow_factory: F,
48 undo_stack: VecDeque<Savepoint>,
49 redo_stack: VecDeque<(EntityId, RF, Vec<EntityId>, i32)>,
50}
51
52impl<RF: Clone, F: WriteRelUoWFactory<RF>> UndoableMoveRelationshipUseCase<RF, F> {
53 pub fn new(uow_factory: F) -> Self {
54 UndoableMoveRelationshipUseCase {
55 uow_factory,
56 undo_stack: VecDeque::new(),
57 redo_stack: VecDeque::new(),
58 }
59 }
60
61 pub fn execute(
62 &mut self,
63 id: &EntityId,
64 field: &RF,
65 ids_to_move: &[EntityId],
66 new_index: i32,
67 ) -> Result<Vec<EntityId>> {
68 let mut uow = self.uow_factory.create();
69 uow.begin_transaction()?;
70 let savepoint = uow.create_savepoint()?;
71 let result = uow.move_relationship(id, field, ids_to_move, new_index)?;
72 uow.commit()?;
73 self.undo_stack.push_back(savepoint);
74 self.redo_stack
75 .push_back((*id, field.clone(), ids_to_move.to_vec(), new_index));
76 Ok(result)
77 }
78}
79
80impl<RF: Clone + Send + 'static, F: WriteRelUoWFactory<RF> + Send + 'static> UndoRedoCommand
81 for UndoableMoveRelationshipUseCase<RF, F>
82{
83 fn undo(&mut self) -> Result<()> {
84 if let Some(savepoint) = self.undo_stack.pop_back() {
85 let mut uow = self.uow_factory.create();
86 uow.begin_transaction()?;
87 uow.restore_to_savepoint(savepoint)?;
88 uow.commit()?;
89 }
90 Ok(())
91 }
92
93 fn redo(&mut self) -> Result<()> {
94 if let Some((id, field, ids_to_move, new_index)) = self.redo_stack.pop_back() {
95 let mut uow = self.uow_factory.create();
96 uow.begin_transaction()?;
97 let savepoint = uow.create_savepoint()?;
98 uow.move_relationship(&id, &field, &ids_to_move, new_index)?;
99 uow.commit()?;
100 self.undo_stack.push_back(savepoint);
101 }
102 Ok(())
103 }
104
105 fn as_any(&self) -> &dyn Any {
106 self
107 }
108}