text_document_common/direct_access/use_cases/
create_orphan.rs1use super::traits::WriteUoWFactory;
4use crate::types::HasId;
5use crate::undo_redo::UndoRedoCommand;
6use anyhow::{Ok, Result};
7use std::any::Any;
8use std::collections::VecDeque;
9
10pub struct CreateOrphanUseCase<F: WriteUoWFactory> {
15 uow_factory: F,
16}
17
18impl<F: WriteUoWFactory> CreateOrphanUseCase<F> {
19 pub fn new(uow_factory: F) -> Self {
20 CreateOrphanUseCase { uow_factory }
21 }
22
23 pub fn execute(&mut self, entity: &F::Entity) -> Result<F::Entity> {
24 let results = self.execute_multi(std::slice::from_ref(entity))?;
25 results
26 .into_iter()
27 .next()
28 .ok_or_else(|| anyhow::anyhow!("Create orphan returned empty"))
29 }
30
31 pub fn execute_multi(&mut self, entities: &[F::Entity]) -> Result<Vec<F::Entity>> {
32 let mut uow = self.uow_factory.create();
33 uow.begin_transaction()?;
34 let created = uow.create_orphan_multi(entities)?;
35 uow.commit()?;
36 Ok(created)
37 }
38}
39
40pub struct UndoableCreateOrphanUseCase<F: WriteUoWFactory> {
45 uow_factory: F,
46 undo_stack: VecDeque<Vec<F::Entity>>,
47 redo_stack: VecDeque<Vec<F::Entity>>,
48}
49
50impl<F: WriteUoWFactory> UndoableCreateOrphanUseCase<F> {
51 pub fn new(uow_factory: F) -> Self {
52 UndoableCreateOrphanUseCase {
53 uow_factory,
54 undo_stack: VecDeque::new(),
55 redo_stack: VecDeque::new(),
56 }
57 }
58
59 pub fn execute(&mut self, entity: &F::Entity) -> Result<F::Entity> {
60 let results = self.execute_multi(std::slice::from_ref(entity))?;
61 results
62 .into_iter()
63 .next()
64 .ok_or_else(|| anyhow::anyhow!("Create orphan returned empty"))
65 }
66
67 pub fn execute_multi(&mut self, entities: &[F::Entity]) -> Result<Vec<F::Entity>> {
68 let mut uow = self.uow_factory.create();
69 uow.begin_transaction()?;
70 let created = uow.create_orphan_multi(entities)?;
71 uow.commit()?;
72 self.undo_stack.push_back(created.clone());
73 self.redo_stack.clear();
74 Ok(created)
75 }
76}
77
78impl<F: WriteUoWFactory + Send + 'static> UndoRedoCommand for UndoableCreateOrphanUseCase<F>
79where
80 F::Entity: 'static,
81{
82 fn undo(&mut self) -> Result<()> {
83 if let Some(last_entities) = self.undo_stack.pop_back() {
84 let mut uow = self.uow_factory.create();
85 uow.begin_transaction()?;
86 uow.remove_multi(&last_entities.iter().map(|e| e.id()).collect::<Vec<_>>())?;
87 uow.commit()?;
88 self.redo_stack.push_back(last_entities);
89 }
90 Ok(())
91 }
92
93 fn redo(&mut self) -> Result<()> {
94 if let Some(last_entities) = self.redo_stack.pop_back() {
95 let mut uow = self.uow_factory.create();
96 uow.begin_transaction()?;
97 uow.create_orphan_multi(&last_entities)?;
98 uow.commit()?;
99 self.undo_stack.push_back(last_entities);
100 }
101 Ok(())
102 }
103
104 fn as_any(&self) -> &dyn Any {
105 self
106 }
107}