ass_editor/commands/script_info_commands/
set.rs1use crate::commands::{CommandResult, EditorCommand};
4use crate::core::{EditorDocument, EditorError, Position, Range, Result};
5
6#[cfg(not(feature = "std"))]
7use alloc::{
8 format,
9 string::{String, ToString},
10};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct SetScriptInfoCommand {
18 pub property: String,
20 pub value: String,
22}
23
24impl SetScriptInfoCommand {
25 pub fn new(property: String, value: String) -> Self {
27 Self { property, value }
28 }
29}
30
31impl EditorCommand for SetScriptInfoCommand {
32 fn execute(&self, document: &mut EditorDocument) -> Result<CommandResult> {
33 let content = document.text().to_string();
34
35 let script_info_start = content
37 .find("[Script Info]")
38 .ok_or_else(|| EditorError::command_failed("No [Script Info] section found"))?;
39
40 let script_info_end = content[script_info_start..]
42 .find("\n[")
43 .map(|pos| script_info_start + pos)
44 .unwrap_or(content.len());
45
46 let property_pattern = format!("{}: ", self.property);
48 let search_range = &content[script_info_start..script_info_end];
49
50 if let Some(prop_pos) = search_range.find(&property_pattern) {
51 let absolute_pos = script_info_start + prop_pos;
53 let line_start = absolute_pos;
54 let line_end = content[absolute_pos..]
55 .find('\n')
56 .map(|pos| absolute_pos + pos)
57 .unwrap_or(content.len());
58
59 let new_line = format!("{}: {}", self.property, self.value);
60 let range = Range::new(Position::new(line_start), Position::new(line_end));
61
62 document.replace(range, &new_line)?;
63
64 Ok(CommandResult::success_with_change(
65 Range::new(
66 Position::new(line_start),
67 Position::new(line_start + new_line.len()),
68 ),
69 Position::new(line_start + new_line.len()),
70 ))
71 } else {
72 let insert_pos = content[script_info_start..]
74 .find('\n')
75 .map(|pos| script_info_start + pos + 1)
76 .unwrap_or(script_info_start + 13); let new_line = format!("{}: {}\n", self.property, self.value);
79 document.insert_raw(Position::new(insert_pos), &new_line)?;
80
81 Ok(CommandResult::success_with_change(
82 Range::new(
83 Position::new(insert_pos),
84 Position::new(insert_pos + new_line.len()),
85 ),
86 Position::new(insert_pos + new_line.len()),
87 ))
88 }
89 }
90
91 fn description(&self) -> &str {
92 "Set script info property"
93 }
94
95 fn memory_usage(&self) -> usize {
96 core::mem::size_of::<Self>() + self.property.len() + self.value.len()
97 }
98}