common/direct_access/use_cases/
move_relationship.rs1use super::traits::WriteRelUoWFactory;
4use crate::types::EntityId;
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<(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}