Skip to main content

text_document_frontend/
flat_event.rs

1// Generated by Qleany v1.7.3 from frontend_flat_event.tera
2
3//! Flat event representation for simplified consumer-side matching.
4//!
5//! Collapses the nested `Origin → DirectAccessEntity → EntityEvent` hierarchy
6//! into a single-level `FlatEventKind` enum. Every consumer can subscribe to
7//! all events once and match on a flat enum instead of reconstructing nested
8//! `Origin` values.
9
10use common::event::{
11    AllEvent, DirectAccessEntity, DocumentEditingEvent, DocumentFormattingEvent,
12    DocumentInspectionEvent, DocumentIoEvent, DocumentSearchEvent, EntityEvent, Event,
13    LongOperationEvent, Origin, UndoRedoEvent,
14};
15use common::types::EntityId;
16
17/// Flat representation of all event origins.
18///
19/// Collapses `Origin → DirectAccessEntity → EntityEvent` into a single level.
20/// Generated from the manifest: adding an entity or feature adds variants,
21/// and the compiler flags every consumer that needs updating.
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23pub enum FlatEventKind {
24    // Per-entity events
25    RootCreated,
26    RootUpdated,
27    RootRemoved,
28    DocumentCreated,
29    DocumentUpdated,
30    DocumentRemoved,
31    FrameCreated,
32    FrameUpdated,
33    FrameRemoved,
34    BlockCreated,
35    BlockUpdated,
36    BlockRemoved,
37    ListCreated,
38    ListUpdated,
39    ListRemoved,
40    ResourceCreated,
41    ResourceUpdated,
42    ResourceRemoved,
43    TableCreated,
44    TableUpdated,
45    TableRemoved,
46    TableCellCreated,
47    TableCellUpdated,
48    TableCellRemoved,
49
50    // Per-feature use case events
51    DocumentEditingInsertText,
52    DocumentEditingDeleteText,
53    DocumentEditingInsertBlock,
54    DocumentEditingInsertImage,
55    DocumentEditingInsertFrame,
56    DocumentEditingInsertFormattedText,
57    DocumentEditingCreateList,
58    DocumentEditingInsertList,
59    DocumentEditingAddBlockToList,
60    DocumentEditingRemoveBlockFromList,
61    DocumentEditingInsertFragment,
62    DocumentEditingInsertHtmlAtPosition,
63    DocumentEditingInsertMarkdownAtPosition,
64    DocumentEditingInsertDjotAtPosition,
65    DocumentEditingInsertTable,
66    DocumentEditingRemoveTable,
67    DocumentEditingInsertTableRow,
68    DocumentEditingInsertTableColumn,
69    DocumentEditingRemoveTableRow,
70    DocumentEditingRemoveTableColumn,
71    DocumentEditingMergeTableCells,
72    DocumentEditingSplitTableCell,
73    DocumentEditingWrapBlocksInFrame,
74    DocumentEditingUnwrapFrame,
75    DocumentEditingUnwrapBlockFromFrame,
76
77    DocumentFormattingSetTextFormat,
78    DocumentFormattingMergeTextFormat,
79    DocumentFormattingSetBlockFormat,
80    DocumentFormattingSetFrameFormat,
81    DocumentFormattingSetTableFormat,
82    DocumentFormattingSetTableCellFormat,
83    DocumentFormattingSetListFormat,
84
85    DocumentIoImportPlainText,
86    DocumentIoExportPlainText,
87    DocumentIoImportMarkdown,
88    DocumentIoExportMarkdown,
89    DocumentIoImportDjot,
90    DocumentIoExportDjot,
91    DocumentIoImportHtml,
92    DocumentIoExportHtml,
93    DocumentIoExportLatex,
94    DocumentIoExportDocx,
95
96    DocumentSearchFindText,
97    DocumentSearchFindAll,
98    DocumentSearchReplaceText,
99    DocumentSearchReplaceRanges,
100    DocumentSearchAddressableText,
101
102    DocumentInspectionGetDocumentStats,
103    DocumentInspectionGetTextAtPosition,
104    DocumentInspectionGetBlockAtPosition,
105    DocumentInspectionExtractFragment,
106
107    // Undo/redo
108    UndoPerformed,
109    RedoPerformed,
110    UndoStackChanged,
111    CompositeBegin,
112    CompositeEnd,
113    CompositeCancelled,
114
115    // Long operations
116    LongOperationStarted,
117    LongOperationProgress,
118    LongOperationCompleted,
119    LongOperationFailed,
120    LongOperationCancelled,
121
122    // System
123    Reset,
124}
125
126/// An event with a flattened kind, ready for consumer-side matching.
127#[derive(Debug, Clone)]
128pub struct FlatEvent {
129    pub kind: FlatEventKind,
130    pub ids: Vec<EntityId>,
131    pub data: Option<String>,
132}
133
134impl From<Event> for FlatEvent {
135    fn from(event: Event) -> Self {
136        let kind = match &event.origin {
137            Origin::DirectAccess(da) => match da {
138                DirectAccessEntity::All(AllEvent::Reset) => FlatEventKind::Reset,
139
140                DirectAccessEntity::Root(EntityEvent::Created) => FlatEventKind::RootCreated,
141                DirectAccessEntity::Root(EntityEvent::Updated) => FlatEventKind::RootUpdated,
142                DirectAccessEntity::Root(EntityEvent::Removed) => FlatEventKind::RootRemoved,
143                DirectAccessEntity::Document(EntityEvent::Created) => {
144                    FlatEventKind::DocumentCreated
145                }
146                DirectAccessEntity::Document(EntityEvent::Updated) => {
147                    FlatEventKind::DocumentUpdated
148                }
149                DirectAccessEntity::Document(EntityEvent::Removed) => {
150                    FlatEventKind::DocumentRemoved
151                }
152                DirectAccessEntity::Frame(EntityEvent::Created) => FlatEventKind::FrameCreated,
153                DirectAccessEntity::Frame(EntityEvent::Updated) => FlatEventKind::FrameUpdated,
154                DirectAccessEntity::Frame(EntityEvent::Removed) => FlatEventKind::FrameRemoved,
155                DirectAccessEntity::Block(EntityEvent::Created) => FlatEventKind::BlockCreated,
156                DirectAccessEntity::Block(EntityEvent::Updated) => FlatEventKind::BlockUpdated,
157                DirectAccessEntity::Block(EntityEvent::Removed) => FlatEventKind::BlockRemoved,
158                DirectAccessEntity::List(EntityEvent::Created) => FlatEventKind::ListCreated,
159                DirectAccessEntity::List(EntityEvent::Updated) => FlatEventKind::ListUpdated,
160                DirectAccessEntity::List(EntityEvent::Removed) => FlatEventKind::ListRemoved,
161                DirectAccessEntity::Resource(EntityEvent::Created) => {
162                    FlatEventKind::ResourceCreated
163                }
164                DirectAccessEntity::Resource(EntityEvent::Updated) => {
165                    FlatEventKind::ResourceUpdated
166                }
167                DirectAccessEntity::Resource(EntityEvent::Removed) => {
168                    FlatEventKind::ResourceRemoved
169                }
170                DirectAccessEntity::Table(EntityEvent::Created) => FlatEventKind::TableCreated,
171                DirectAccessEntity::Table(EntityEvent::Updated) => FlatEventKind::TableUpdated,
172                DirectAccessEntity::Table(EntityEvent::Removed) => FlatEventKind::TableRemoved,
173                DirectAccessEntity::TableCell(EntityEvent::Created) => {
174                    FlatEventKind::TableCellCreated
175                }
176                DirectAccessEntity::TableCell(EntityEvent::Updated) => {
177                    FlatEventKind::TableCellUpdated
178                }
179                DirectAccessEntity::TableCell(EntityEvent::Removed) => {
180                    FlatEventKind::TableCellRemoved
181                }
182            },
183
184            Origin::DocumentEditing(fe) => match fe {
185                DocumentEditingEvent::InsertText => FlatEventKind::DocumentEditingInsertText,
186                DocumentEditingEvent::DeleteText => FlatEventKind::DocumentEditingDeleteText,
187                DocumentEditingEvent::InsertBlock => FlatEventKind::DocumentEditingInsertBlock,
188                DocumentEditingEvent::InsertImage => FlatEventKind::DocumentEditingInsertImage,
189                DocumentEditingEvent::InsertFrame => FlatEventKind::DocumentEditingInsertFrame,
190                DocumentEditingEvent::InsertFormattedText => {
191                    FlatEventKind::DocumentEditingInsertFormattedText
192                }
193                DocumentEditingEvent::CreateList => FlatEventKind::DocumentEditingCreateList,
194                DocumentEditingEvent::InsertList => FlatEventKind::DocumentEditingInsertList,
195                DocumentEditingEvent::AddBlockToList => {
196                    FlatEventKind::DocumentEditingAddBlockToList
197                }
198                DocumentEditingEvent::RemoveBlockFromList => {
199                    FlatEventKind::DocumentEditingRemoveBlockFromList
200                }
201                DocumentEditingEvent::InsertFragment => {
202                    FlatEventKind::DocumentEditingInsertFragment
203                }
204                DocumentEditingEvent::InsertHtmlAtPosition => {
205                    FlatEventKind::DocumentEditingInsertHtmlAtPosition
206                }
207                DocumentEditingEvent::InsertMarkdownAtPosition => {
208                    FlatEventKind::DocumentEditingInsertMarkdownAtPosition
209                }
210                DocumentEditingEvent::InsertDjotAtPosition => {
211                    FlatEventKind::DocumentEditingInsertDjotAtPosition
212                }
213                DocumentEditingEvent::InsertTable => FlatEventKind::DocumentEditingInsertTable,
214                DocumentEditingEvent::RemoveTable => FlatEventKind::DocumentEditingRemoveTable,
215                DocumentEditingEvent::InsertTableRow => {
216                    FlatEventKind::DocumentEditingInsertTableRow
217                }
218                DocumentEditingEvent::InsertTableColumn => {
219                    FlatEventKind::DocumentEditingInsertTableColumn
220                }
221                DocumentEditingEvent::RemoveTableRow => {
222                    FlatEventKind::DocumentEditingRemoveTableRow
223                }
224                DocumentEditingEvent::RemoveTableColumn => {
225                    FlatEventKind::DocumentEditingRemoveTableColumn
226                }
227                DocumentEditingEvent::MergeTableCells => {
228                    FlatEventKind::DocumentEditingMergeTableCells
229                }
230                DocumentEditingEvent::SplitTableCell => {
231                    FlatEventKind::DocumentEditingSplitTableCell
232                }
233                DocumentEditingEvent::WrapBlocksInFrame => {
234                    FlatEventKind::DocumentEditingWrapBlocksInFrame
235                }
236                DocumentEditingEvent::UnwrapFrame => FlatEventKind::DocumentEditingUnwrapFrame,
237                DocumentEditingEvent::UnwrapBlockFromFrame => {
238                    FlatEventKind::DocumentEditingUnwrapBlockFromFrame
239                }
240            },
241            Origin::DocumentFormatting(fe) => match fe {
242                DocumentFormattingEvent::SetTextFormat => {
243                    FlatEventKind::DocumentFormattingSetTextFormat
244                }
245                DocumentFormattingEvent::MergeTextFormat => {
246                    FlatEventKind::DocumentFormattingMergeTextFormat
247                }
248                DocumentFormattingEvent::SetBlockFormat => {
249                    FlatEventKind::DocumentFormattingSetBlockFormat
250                }
251                DocumentFormattingEvent::SetFrameFormat => {
252                    FlatEventKind::DocumentFormattingSetFrameFormat
253                }
254                DocumentFormattingEvent::SetTableFormat => {
255                    FlatEventKind::DocumentFormattingSetTableFormat
256                }
257                DocumentFormattingEvent::SetTableCellFormat => {
258                    FlatEventKind::DocumentFormattingSetTableCellFormat
259                }
260                DocumentFormattingEvent::SetListFormat => {
261                    FlatEventKind::DocumentFormattingSetListFormat
262                }
263            },
264            Origin::DocumentIo(fe) => match fe {
265                DocumentIoEvent::ImportPlainText => FlatEventKind::DocumentIoImportPlainText,
266                DocumentIoEvent::ExportPlainText => FlatEventKind::DocumentIoExportPlainText,
267                DocumentIoEvent::ImportMarkdown => FlatEventKind::DocumentIoImportMarkdown,
268                DocumentIoEvent::ExportMarkdown => FlatEventKind::DocumentIoExportMarkdown,
269                DocumentIoEvent::ImportDjot => FlatEventKind::DocumentIoImportDjot,
270                DocumentIoEvent::ExportDjot => FlatEventKind::DocumentIoExportDjot,
271                DocumentIoEvent::ImportHtml => FlatEventKind::DocumentIoImportHtml,
272                DocumentIoEvent::ExportHtml => FlatEventKind::DocumentIoExportHtml,
273                DocumentIoEvent::ExportLatex => FlatEventKind::DocumentIoExportLatex,
274                DocumentIoEvent::ExportDocx => FlatEventKind::DocumentIoExportDocx,
275            },
276            Origin::DocumentSearch(fe) => match fe {
277                DocumentSearchEvent::FindText => FlatEventKind::DocumentSearchFindText,
278                DocumentSearchEvent::FindAll => FlatEventKind::DocumentSearchFindAll,
279                DocumentSearchEvent::ReplaceText => FlatEventKind::DocumentSearchReplaceText,
280                DocumentSearchEvent::ReplaceRanges => FlatEventKind::DocumentSearchReplaceRanges,
281                DocumentSearchEvent::AddressableText => {
282                    FlatEventKind::DocumentSearchAddressableText
283                }
284            },
285            Origin::DocumentInspection(fe) => match fe {
286                DocumentInspectionEvent::GetDocumentStats => {
287                    FlatEventKind::DocumentInspectionGetDocumentStats
288                }
289                DocumentInspectionEvent::GetTextAtPosition => {
290                    FlatEventKind::DocumentInspectionGetTextAtPosition
291                }
292                DocumentInspectionEvent::GetBlockAtPosition => {
293                    FlatEventKind::DocumentInspectionGetBlockAtPosition
294                }
295                DocumentInspectionEvent::ExtractFragment => {
296                    FlatEventKind::DocumentInspectionExtractFragment
297                }
298            },
299            Origin::UndoRedo(ur) => match ur {
300                UndoRedoEvent::Undone => FlatEventKind::UndoPerformed,
301                UndoRedoEvent::Redone => FlatEventKind::RedoPerformed,
302                UndoRedoEvent::StackChanged => FlatEventKind::UndoStackChanged,
303                UndoRedoEvent::BeginComposite => FlatEventKind::CompositeBegin,
304                UndoRedoEvent::EndComposite => FlatEventKind::CompositeEnd,
305                UndoRedoEvent::CancelComposite => FlatEventKind::CompositeCancelled,
306            },
307            Origin::LongOperation(lo) => match lo {
308                LongOperationEvent::Started => FlatEventKind::LongOperationStarted,
309                LongOperationEvent::Progress => FlatEventKind::LongOperationProgress,
310                LongOperationEvent::Completed => FlatEventKind::LongOperationCompleted,
311                LongOperationEvent::Failed => FlatEventKind::LongOperationFailed,
312                LongOperationEvent::Cancelled => FlatEventKind::LongOperationCancelled,
313            },
314        };
315        FlatEvent {
316            kind,
317            ids: event.ids,
318            data: event.data,
319        }
320    }
321}
322
323/// Returns `true` if this event kind represents an entity mutation (created, updated, or removed).
324pub fn is_mutation(kind: &FlatEventKind) -> bool {
325    use FlatEventKind::*;
326    matches!(
327        kind,
328        RootCreated
329            | RootUpdated
330            | RootRemoved
331            | DocumentCreated
332            | DocumentUpdated
333            | DocumentRemoved
334            | FrameCreated
335            | FrameUpdated
336            | FrameRemoved
337            | BlockCreated
338            | BlockUpdated
339            | BlockRemoved
340            | ListCreated
341            | ListUpdated
342            | ListRemoved
343            | ResourceCreated
344            | ResourceUpdated
345            | ResourceRemoved
346            | TableCreated
347            | TableUpdated
348            | TableRemoved
349            | TableCellCreated
350            | TableCellUpdated
351            | TableCellRemoved
352    )
353}
354
355#[cfg(test)]
356mod tests {
357    use super::*;
358
359    #[test]
360    fn test_entity_event_converts_to_flat() {
361        let event = Event {
362            origin: Origin::DirectAccess(DirectAccessEntity::All(AllEvent::Reset)),
363            ids: vec![],
364            data: None,
365        };
366        let flat: FlatEvent = event.into();
367        assert_eq!(flat.kind, FlatEventKind::Reset);
368    }
369
370    #[test]
371    fn test_undo_redo_converts_to_flat() {
372        let event = Event {
373            origin: Origin::UndoRedo(UndoRedoEvent::Undone),
374            ids: vec![],
375            data: None,
376        };
377        let flat: FlatEvent = event.into();
378        assert_eq!(flat.kind, FlatEventKind::UndoPerformed);
379    }
380
381    #[test]
382    fn test_stack_changed_converts_to_flat_and_keeps_its_stack_id() {
383        // The stack id travels in `data`, not `ids` — `ids` means *entity* ids.
384        // A subscriber holding one stack per open document has no other way to
385        // tell whose history moved, so losing it here would make the event
386        // useless to exactly the consumer it was added for.
387        let event = Event {
388            origin: Origin::UndoRedo(UndoRedoEvent::StackChanged),
389            ids: vec![],
390            data: Some("7".to_string()),
391        };
392        let flat: FlatEvent = event.into();
393        assert_eq!(flat.kind, FlatEventKind::UndoStackChanged);
394        assert_eq!(flat.data.as_deref(), Some("7"));
395    }
396
397    #[test]
398    fn test_is_mutation() {
399        assert!(is_mutation(&FlatEventKind::RootCreated));
400        assert!(is_mutation(&FlatEventKind::RootUpdated));
401        assert!(is_mutation(&FlatEventKind::RootRemoved));
402
403        assert!(is_mutation(&FlatEventKind::DocumentCreated));
404        assert!(is_mutation(&FlatEventKind::DocumentUpdated));
405        assert!(is_mutation(&FlatEventKind::DocumentRemoved));
406
407        assert!(is_mutation(&FlatEventKind::FrameCreated));
408        assert!(is_mutation(&FlatEventKind::FrameUpdated));
409        assert!(is_mutation(&FlatEventKind::FrameRemoved));
410
411        assert!(is_mutation(&FlatEventKind::BlockCreated));
412        assert!(is_mutation(&FlatEventKind::BlockUpdated));
413        assert!(is_mutation(&FlatEventKind::BlockRemoved));
414
415        assert!(is_mutation(&FlatEventKind::ListCreated));
416        assert!(is_mutation(&FlatEventKind::ListUpdated));
417        assert!(is_mutation(&FlatEventKind::ListRemoved));
418
419        assert!(is_mutation(&FlatEventKind::ResourceCreated));
420        assert!(is_mutation(&FlatEventKind::ResourceUpdated));
421        assert!(is_mutation(&FlatEventKind::ResourceRemoved));
422
423        assert!(is_mutation(&FlatEventKind::TableCreated));
424        assert!(is_mutation(&FlatEventKind::TableUpdated));
425        assert!(is_mutation(&FlatEventKind::TableRemoved));
426
427        assert!(is_mutation(&FlatEventKind::TableCellCreated));
428        assert!(is_mutation(&FlatEventKind::TableCellUpdated));
429        assert!(is_mutation(&FlatEventKind::TableCellRemoved));
430
431        assert!(!is_mutation(&FlatEventKind::Reset));
432        assert!(!is_mutation(&FlatEventKind::UndoPerformed));
433        // History growing is not the store changing: the entity events the
434        // command itself published inside its own transaction are what the
435        // generic refresh path reacts to. Counting this one too would repaint
436        // every model a second time for every keystroke.
437        assert!(!is_mutation(&FlatEventKind::UndoStackChanged));
438        assert!(!is_mutation(&FlatEventKind::LongOperationStarted));
439    }
440}