Skip to main content

ass_core/
version.rs

1//! ASS script version detection and feature support.
2//!
3//! Defines [`ScriptVersion`], which identifies the SSA/ASS format variant a
4//! script declares and whether it supports modern libass 0.17.4+ extensions.
5
6/// Supported ASS script versions for compatibility and feature detection.
7///
8/// ASS scripts can declare different versions that affect parsing behavior
9/// and available features. This enum helps determine which parsing mode
10/// to use and which features are available.
11///
12/// # Examples
13///
14/// ```rust
15/// use ass_core::ScriptVersion;
16///
17/// // Parse from header
18/// let version = ScriptVersion::from_header("v4.00+").unwrap();
19/// assert_eq!(version, ScriptVersion::AssV4);
20///
21/// // Check feature support
22/// assert!(!ScriptVersion::SsaV4.supports_extensions());
23/// assert!(ScriptVersion::AssV4Plus.supports_extensions());
24/// ```
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize))]
27pub enum ScriptVersion {
28    /// SSA v4.00 (`SubStation` Alpha legacy format).
29    ///
30    /// Provides compatibility with legacy SSA files. Limited feature set
31    /// compared to modern ASS versions.
32    SsaV4,
33    /// ASS v4.00+ (Advanced `SubStation` Alpha standard).
34    ///
35    /// The most common format used by modern subtitle tools. Supports
36    /// all standard ASS features and tags.
37    AssV4,
38    /// ASS v4.00+ with extensions (libass 0.17.4+ compatibility).
39    ///
40    /// Extended format supporting newer features like `\kt` karaoke tags,
41    /// Unicode line wrapping, and other libass extensions.
42    AssV4Plus,
43}
44
45impl ScriptVersion {
46    /// Parse script version from a `ScriptType` header value.
47    ///
48    /// Converts header strings commonly found in `[Script Info]` sections
49    /// to the appropriate script version enum. Handles various formats
50    /// including extended versions.
51    ///
52    /// # Arguments
53    ///
54    /// * `header` - The header value string (usually from `ScriptType` field)
55    ///
56    /// # Returns
57    ///
58    /// Returns `Some(ScriptVersion)` if the header is recognized, or `None`
59    /// if the version string is invalid or unsupported.
60    ///
61    /// # Examples
62    ///
63    /// ```rust
64    /// use ass_core::ScriptVersion;
65    ///
66    /// assert_eq!(ScriptVersion::from_header("v4.00"), Some(ScriptVersion::SsaV4));
67    /// assert_eq!(ScriptVersion::from_header("v4.00+"), Some(ScriptVersion::AssV4));
68    /// assert_eq!(ScriptVersion::from_header("v4.00++"), Some(ScriptVersion::AssV4Plus));
69    /// assert_eq!(ScriptVersion::from_header("invalid"), None);
70    /// ```
71    #[must_use]
72    pub fn from_header(header: &str) -> Option<Self> {
73        match header.trim() {
74            "v4.00" => Some(Self::SsaV4),
75            "v4.00+" => Some(Self::AssV4),
76            "v4.00++" | "v4.00+ extended" => Some(Self::AssV4Plus),
77            _ => None,
78        }
79    }
80
81    /// Check if the script version supports modern ASS extensions.
82    ///
83    /// Modern ASS extensions include features like:
84    /// - `\kt` karaoke timing tags
85    /// - Unicode line wrapping
86    /// - Extended color formats
87    /// - Advanced animation features
88    ///
89    /// Only `AssV4Plus` currently supports these extensions, as they
90    /// require libass 0.17.4+ compatibility.
91    ///
92    /// # Returns
93    ///
94    /// Returns `true` if the version supports extensions, `false` otherwise.
95    ///
96    /// # Examples
97    ///
98    /// ```rust
99    /// use ass_core::ScriptVersion;
100    ///
101    /// assert!(!ScriptVersion::SsaV4.supports_extensions());
102    /// assert!(!ScriptVersion::AssV4.supports_extensions());
103    /// assert!(ScriptVersion::AssV4Plus.supports_extensions());
104    /// ```
105    #[must_use]
106    pub const fn supports_extensions(self) -> bool {
107        matches!(self, Self::AssV4Plus)
108    }
109}