ass_editor/commands/
text_commands.rs1use crate::core::{EditorDocument, Position, Range, Result};
4
5use super::{CommandResult, EditorCommand};
6
7#[cfg(not(feature = "std"))]
8use alloc::string::String;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct InsertTextCommand {
13 pub position: Position,
15 pub text: String,
17 pub description: Option<String>,
19}
20
21impl InsertTextCommand {
22 pub fn new(position: Position, text: String) -> Self {
37 Self {
38 position,
39 text,
40 description: None,
41 }
42 }
43
44 #[must_use]
46 pub fn with_description(mut self, description: String) -> Self {
47 self.description = Some(description);
48 self
49 }
50}
51
52impl EditorCommand for InsertTextCommand {
53 fn execute(&self, document: &mut EditorDocument) -> Result<CommandResult> {
54 document.insert_raw(self.position, &self.text)?;
55
56 let end_pos = Position::new(self.position.offset + self.text.len());
57 let range = Range::new(self.position, end_pos);
58
59 Ok(CommandResult::success_with_change(range, end_pos))
60 }
61
62 fn description(&self) -> &str {
63 self.description.as_deref().unwrap_or("Insert text")
64 }
65
66 fn memory_usage(&self) -> usize {
67 core::mem::size_of::<Self>()
68 + self.text.len()
69 + self.description.as_ref().map_or(0, |d| d.len())
70 }
71}
72
73#[derive(Debug, Clone, PartialEq, Eq)]
75pub struct DeleteTextCommand {
76 pub range: Range,
78 pub description: Option<String>,
80}
81
82impl DeleteTextCommand {
83 pub fn new(range: Range) -> Self {
85 Self {
86 range,
87 description: None,
88 }
89 }
90
91 #[must_use]
93 pub fn with_description(mut self, description: String) -> Self {
94 self.description = Some(description);
95 self
96 }
97}
98
99impl EditorCommand for DeleteTextCommand {
100 fn execute(&self, document: &mut EditorDocument) -> Result<CommandResult> {
101 document.delete_raw(self.range)?;
102
103 let cursor_pos = self.range.start;
104 let range = Range::new(self.range.start, self.range.start);
105
106 Ok(CommandResult::success_with_change(range, cursor_pos))
107 }
108
109 fn description(&self) -> &str {
110 self.description.as_deref().unwrap_or("Delete text")
111 }
112}
113
114#[derive(Debug, Clone, PartialEq, Eq)]
116pub struct ReplaceTextCommand {
117 pub range: Range,
119 pub new_text: String,
121 pub description: Option<String>,
123}
124
125impl ReplaceTextCommand {
126 pub fn new(range: Range, new_text: String) -> Self {
128 Self {
129 range,
130 new_text,
131 description: None,
132 }
133 }
134
135 #[must_use]
137 pub fn with_description(mut self, description: String) -> Self {
138 self.description = Some(description);
139 self
140 }
141}
142
143impl EditorCommand for ReplaceTextCommand {
144 fn execute(&self, document: &mut EditorDocument) -> Result<CommandResult> {
145 document.replace_raw(self.range, &self.new_text)?;
146
147 let end_pos = Position::new(self.range.start.offset + self.new_text.len());
148 let range = Range::new(self.range.start, end_pos);
149
150 Ok(CommandResult::success_with_change(range, end_pos))
151 }
152
153 fn description(&self) -> &str {
154 self.description.as_deref().unwrap_or("Replace text")
155 }
156
157 fn memory_usage(&self) -> usize {
158 core::mem::size_of::<Self>()
159 + self.new_text.len()
160 + self.description.as_ref().map_or(0, |d| d.len())
161 }
162}