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}