use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
extern crate alloc;
use super::Span;
#[cfg(debug_assertions)]
use core::ops::Range;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct ScriptInfo<'a> {
pub fields: Vec<(&'a str, &'a str)>,
pub span: Span,
}
impl<'a> ScriptInfo<'a> {
#[must_use]
pub fn get_field(&self, key: &str) -> Option<&'a str> {
self.fields.iter().find(|(k, _)| *k == key).map(|(_, v)| *v)
}
#[must_use]
pub fn title(&self) -> &str {
self.get_field("Title").unwrap_or("<untitled>")
}
#[must_use]
pub fn script_type(&self) -> Option<&'a str> {
self.get_field("ScriptType")
}
#[must_use]
pub fn play_resolution(&self) -> Option<(u32, u32)> {
let width = self.get_field("PlayResX")?.parse().ok()?;
let height = self.get_field("PlayResY")?.parse().ok()?;
Some((width, height))
}
#[must_use]
pub fn layout_resolution(&self) -> Option<(u32, u32)> {
let width = self.get_field("LayoutResX")?.parse().ok()?;
let height = self.get_field("LayoutResY")?.parse().ok()?;
Some((width, height))
}
#[must_use]
pub fn wrap_style(&self) -> u8 {
self.get_field("WrapStyle")
.and_then(|s| s.parse().ok())
.unwrap_or(0)
}
#[must_use]
pub fn to_ass_string(&self) -> alloc::string::String {
use core::fmt::Write;
let mut result = alloc::string::String::from("[Script Info]\n");
for (key, value) in &self.fields {
let _ = writeln!(result, "{key}: {value}");
}
result
}
#[cfg(debug_assertions)]
#[must_use]
pub fn validate_spans(&self, source_range: &Range<usize>) -> bool {
self.fields.iter().all(|(key, value)| {
let key_ptr = key.as_ptr() as usize;
let value_ptr = value.as_ptr() as usize;
source_range.contains(&key_ptr) && source_range.contains(&value_ptr)
})
}
}