ff_encode/shared/
container.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11#[non_exhaustive]
12pub enum OutputContainer {
13 Mp4,
15
16 FMp4,
23
24 WebM,
26
27 Mkv,
29
30 Avi,
32
33 Mov,
35
36 Flac,
38
39 Ogg,
41}
42
43impl OutputContainer {
44 #[must_use]
46 pub const fn as_str(self) -> &'static str {
47 match self {
48 Self::Mp4 | Self::FMp4 => "mp4",
49 Self::WebM => "webm",
50 Self::Mkv => "matroska",
51 Self::Avi => "avi",
52 Self::Mov => "mov",
53 Self::Flac => "flac",
54 Self::Ogg => "ogg",
55 }
56 }
57
58 #[must_use]
60 pub const fn default_extension(self) -> &'static str {
61 match self {
62 Self::Mp4 | Self::FMp4 => "mp4",
63 Self::WebM => "webm",
64 Self::Mkv => "mkv",
65 Self::Avi => "avi",
66 Self::Mov => "mov",
67 Self::Flac => "flac",
68 Self::Ogg => "ogg",
69 }
70 }
71
72 #[must_use]
79 pub fn from_path(path: &std::path::Path) -> Option<Self> {
80 let ext = path.extension()?.to_str()?.to_ascii_lowercase();
81 match ext.as_str() {
82 "mp4" | "m4v" => Some(Self::Mp4),
83 "webm" => Some(Self::WebM),
84 "mkv" => Some(Self::Mkv),
85 "avi" => Some(Self::Avi),
86 "mov" => Some(Self::Mov),
87 "flac" => Some(Self::Flac),
88 "ogg" => Some(Self::Ogg),
89 _ => None,
90 }
91 }
92
93 #[must_use]
99 pub const fn is_fragmented(self) -> bool {
100 matches!(self, Self::FMp4)
101 }
102
103 #[must_use]
111 pub const fn supports_faststart(self) -> bool {
112 matches!(self, Self::Mp4 | Self::Mov)
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 #[test]
121 fn test_container_as_str() {
122 assert_eq!(OutputContainer::Mp4.as_str(), "mp4");
123 assert_eq!(OutputContainer::WebM.as_str(), "webm");
124 assert_eq!(OutputContainer::Mkv.as_str(), "matroska");
125 }
126
127 #[test]
128 fn test_container_extension() {
129 assert_eq!(OutputContainer::Mp4.default_extension(), "mp4");
130 assert_eq!(OutputContainer::WebM.default_extension(), "webm");
131 assert_eq!(OutputContainer::Mkv.default_extension(), "mkv");
132 assert_eq!(OutputContainer::Flac.default_extension(), "flac");
133 assert_eq!(OutputContainer::Ogg.default_extension(), "ogg");
134 }
135
136 #[test]
137 fn flac_as_str_should_return_flac() {
138 assert_eq!(OutputContainer::Flac.as_str(), "flac");
139 }
140
141 #[test]
142 fn ogg_as_str_should_return_ogg() {
143 assert_eq!(OutputContainer::Ogg.as_str(), "ogg");
144 }
145
146 #[test]
147 fn fmp4_as_str_should_return_mp4() {
148 assert_eq!(OutputContainer::FMp4.as_str(), "mp4");
149 }
150
151 #[test]
152 fn fmp4_extension_should_return_mp4() {
153 assert_eq!(OutputContainer::FMp4.default_extension(), "mp4");
154 }
155
156 #[test]
157 fn fmp4_is_fragmented_should_return_true() {
158 assert!(OutputContainer::FMp4.is_fragmented());
159 assert!(!OutputContainer::Mp4.is_fragmented());
160 assert!(!OutputContainer::Mkv.is_fragmented());
161 }
162
163 #[test]
164 fn from_path_should_map_known_extensions_case_insensitively() {
165 use std::path::Path;
166 assert_eq!(
167 OutputContainer::from_path(Path::new("out.mp4")),
168 Some(OutputContainer::Mp4)
169 );
170 assert_eq!(
172 OutputContainer::from_path(Path::new("OUT.MP4")),
173 Some(OutputContainer::Mp4)
174 );
175 assert_eq!(
176 OutputContainer::from_path(Path::new("clip.mov")),
177 Some(OutputContainer::Mov)
178 );
179 assert_eq!(
180 OutputContainer::from_path(Path::new("clip.mkv")),
181 Some(OutputContainer::Mkv)
182 );
183 assert_eq!(OutputContainer::from_path(Path::new("clip.xyz")), None);
184 assert_eq!(OutputContainer::from_path(Path::new("noext")), None);
185 }
186
187 #[test]
188 fn supports_faststart_should_be_true_for_mp4_and_mov() {
189 assert!(OutputContainer::Mp4.supports_faststart());
190 assert!(OutputContainer::Mov.supports_faststart());
191 assert!(!OutputContainer::FMp4.supports_faststart());
193 assert!(!OutputContainer::WebM.supports_faststart());
194 assert!(!OutputContainer::Mkv.supports_faststart());
195 }
196}