Skip to main content

ass_editor/core/fluent/
script_info.rs

1//! Fluent API for managing Script Info properties.
2
3use crate::commands::{
4    DeleteScriptInfoCommand, EditorCommand, GetAllScriptInfoCommand, GetScriptInfoCommand,
5    SetScriptInfoCommand,
6};
7use crate::core::errors::EditorError;
8use crate::core::{EditorDocument, Result};
9
10#[cfg(not(feature = "std"))]
11use alloc::{
12    string::{String, ToString},
13    vec::Vec,
14};
15
16/// Fluent API for managing Script Info properties
17pub struct ScriptInfoOps<'a> {
18    document: &'a mut EditorDocument,
19}
20
21impl<'a> ScriptInfoOps<'a> {
22    /// Create new script info operations
23    pub(crate) fn new(document: &'a mut EditorDocument) -> Self {
24        Self { document }
25    }
26
27    /// Set a script info property
28    pub fn set(self, property: &str, value: &str) -> Result<&'a mut EditorDocument> {
29        let command = SetScriptInfoCommand::new(property.to_string(), value.to_string());
30        command.execute(self.document)?;
31        Ok(self.document)
32    }
33
34    /// Get a script info property value
35    pub fn get(&self, property: &str) -> Result<Option<String>> {
36        let command = GetScriptInfoCommand::new(property.to_string());
37        command.get_value(self.document)
38    }
39
40    /// Delete a script info property
41    pub fn delete(self, property: &str) -> Result<&'a mut EditorDocument> {
42        let command = DeleteScriptInfoCommand::new(property.to_string());
43        command.execute(self.document)?;
44        Ok(self.document)
45    }
46
47    /// Get all script info properties
48    pub fn all(&self) -> Result<Vec<(String, String)>> {
49        let command = GetAllScriptInfoCommand::new();
50        command.get_all(self.document)
51    }
52
53    /// Set the title
54    pub fn title(self, title: &str) -> Result<&'a mut EditorDocument> {
55        self.set("Title", title)
56    }
57
58    /// Get the title
59    pub fn get_title(&self) -> Result<Option<String>> {
60        self.get("Title")
61    }
62
63    /// Set the author
64    pub fn author(self, author: &str) -> Result<&'a mut EditorDocument> {
65        self.set("Original Script", author)
66    }
67
68    /// Get the author
69    pub fn get_author(&self) -> Result<Option<String>> {
70        self.get("Original Script")
71    }
72
73    /// Set the resolution
74    pub fn resolution(self, width: u32, height: u32) -> Result<&'a mut EditorDocument> {
75        let command1 = SetScriptInfoCommand::new("PlayResX".to_string(), width.to_string());
76        let command2 = SetScriptInfoCommand::new("PlayResY".to_string(), height.to_string());
77        command1.execute(self.document)?;
78        command2.execute(self.document)?;
79        Ok(self.document)
80    }
81
82    /// Get the resolution
83    pub fn get_resolution(&self) -> Result<Option<(u32, u32)>> {
84        let width_cmd = GetScriptInfoCommand::new("PlayResX".to_string());
85        let height_cmd = GetScriptInfoCommand::new("PlayResY".to_string());
86
87        let width = width_cmd.get_value(self.document)?;
88        let height = height_cmd.get_value(self.document)?;
89
90        match (width, height) {
91            (Some(w), Some(h)) => {
92                let width_val = w
93                    .parse::<u32>()
94                    .map_err(|_| EditorError::command_failed("Invalid PlayResX value"))?;
95                let height_val = h
96                    .parse::<u32>()
97                    .map_err(|_| EditorError::command_failed("Invalid PlayResY value"))?;
98                Ok(Some((width_val, height_val)))
99            }
100            _ => Ok(None),
101        }
102    }
103
104    /// Set the wrap style
105    pub fn wrap_style(self, style: u8) -> Result<&'a mut EditorDocument> {
106        self.set("WrapStyle", &style.to_string())
107    }
108
109    /// Get the wrap style
110    pub fn get_wrap_style(&self) -> Result<Option<u8>> {
111        self.get("WrapStyle")?
112            .map(|s| {
113                s.parse::<u8>()
114                    .map_err(|_| EditorError::command_failed("Invalid WrapStyle value"))
115            })
116            .transpose()
117    }
118
119    /// Set scaled border and shadow
120    pub fn scaled_border_and_shadow(self, scaled: bool) -> Result<&'a mut EditorDocument> {
121        let value = if scaled { "yes" } else { "no" };
122        self.set("ScaledBorderAndShadow", value)
123    }
124
125    /// Get scaled border and shadow setting
126    pub fn get_scaled_border_and_shadow(&self) -> Result<Option<bool>> {
127        Ok(self
128            .get("ScaledBorderAndShadow")?
129            .map(|s| s.to_lowercase() == "yes" || s == "1"))
130    }
131}