strop_engine/editor/transact/
capability.rs1use super::super::{Document, Editor};
3use std::ops::{Deref, DerefMut};
4use strop_core::id::{ByteOffset, DocumentId};
5use strop_core::{Buffer, Range};
6
7pub struct DocumentEdit<'a> {
8 editor: &'a mut Editor,
9 document: DocumentId,
10 map_active: bool,
11}
12impl<'a> DocumentEdit<'a> {
13 pub(crate) fn new(editor: &'a mut Editor, document: DocumentId) -> Self {
14 assert!(
15 editor.docs.get(document).is_some(),
16 "mutation lease requires a live document"
17 );
18 Self {
19 editor,
20 document,
21 map_active: true,
22 }
23 }
24
25 pub(crate) fn replace_snapshot(
29 mut self,
30 rope: ropey::Rope,
31 position: impl Fn(usize) -> usize,
32 ) -> Result<(), strop_core::EditError> {
33 debug_assert!(self.buf.changes().is_empty());
34 self.buf.system_edit().replace_rope(rope)?;
35 self.editor
36 .sync_document_positions(self.document, true, |offset, _| position(offset));
37 Ok(())
38 }
39}
40impl Deref for DocumentEdit<'_> {
41 type Target = Document;
42 fn deref(&self) -> &Document {
43 match self.editor.docs.get(self.document) {
44 Some(document) => document,
45 None => unreachable!("exclusive mutation lease preserves its document"),
46 }
47 }
48}
49impl DerefMut for DocumentEdit<'_> {
50 fn deref_mut(&mut self) -> &mut Document {
51 match self.editor.docs.get_mut(self.document) {
52 Some(document) => document,
53 None => unreachable!("exclusive mutation lease preserves its document"),
54 }
55 }
56}
57impl Drop for DocumentEdit<'_> {
58 fn drop(&mut self) {
59 self.editor.sync_document(self.document, self.map_active);
60 }
61}
62
63pub struct BufferEdit<'a>(DocumentEdit<'a>);
64impl<'a> BufferEdit<'a> {
65 pub(crate) fn new(mut document: DocumentEdit<'a>) -> Self {
66 document.map_active = false;
69 Self(document)
70 }
71 pub fn insert(&mut self, at: impl Into<ByteOffset>, text: &str) -> bool {
72 match self.0.buf.edit().insert(at, text) {
73 Ok(()) => true,
74 Err(error) => {
75 self.0.editor.message = format!("edit failed: {error}");
76 false
77 }
78 }
79 }
80 pub fn delete(&mut self, range: Range) -> String {
81 match self.0.buf.edit().delete(range) {
82 Ok(text) => text,
83 Err(error) => {
84 self.0.editor.message = format!("edit failed: {error}");
85 String::new()
86 }
87 }
88 }
89}
90impl Deref for BufferEdit<'_> {
91 type Target = Buffer;
92 fn deref(&self) -> &Buffer {
93 &self.0.buf
94 }
95}
96impl DerefMut for BufferEdit<'_> {
97 fn deref_mut(&mut self) -> &mut Buffer {
98 &mut self.0.buf
99 }
100}