1use crate::detect::Format;
11use crate::formats::MetadataHandler;
12use crate::formats::flac::FlacHandler;
13use crate::formats::gif::GifHandler;
14use crate::formats::heif::HeifHandler;
15use crate::formats::jpeg::JpegHandler;
16use crate::formats::jxl::JxlHandler;
17use crate::formats::mp3::Mp3Handler;
18use crate::formats::mp4::Mp4Handler;
19use crate::formats::odf::OdfHandler;
20use crate::formats::ogg::OggHandler;
21use crate::formats::ooxml::OoxmlHandler;
22use crate::formats::pdf::PdfHandler;
23use crate::formats::png::PngHandler;
24use crate::formats::svg::SvgHandler;
25use crate::formats::tiff::TiffHandler;
26use crate::formats::wav::WavHandler;
27use crate::formats::webp::WebpHandler;
28
29#[must_use]
36pub fn handler_for(format: Format) -> Option<&'static dyn MetadataHandler> {
37 match format {
38 Format::Jpeg => Some(&JpegHandler),
39 Format::Pdf => Some(&PdfHandler),
40 Format::Png => Some(&PngHandler),
41 Format::Tiff => Some(&TiffHandler),
42 Format::Gif => Some(&GifHandler),
43 Format::Svg => Some(&SvgHandler),
44 Format::Jxl => Some(&JxlHandler),
45 Format::Flac => Some(&FlacHandler),
46 Format::Wav => Some(&WavHandler),
47 Format::Mp3 => Some(&Mp3Handler),
48 Format::Heif => Some(&HEIF),
51 Format::Mp4 => Some(&MP4),
54 Format::M4a => Some(&M4A),
55 Format::Ogg => Some(&OGG_VORBIS),
57 Format::Opus => Some(&OPUS),
58 Format::OggFlac => Some(&OGG_FLAC),
59 Format::Avif => Some(&AVIF),
60 Format::Webp => Some(&WebpHandler),
61 Format::Docx => Some(&DOCX),
65 Format::Xlsx => Some(&XLSX),
66 Format::Pptx => Some(&PPTX),
67 Format::Odt => Some(&ODT),
68 Format::Ods => Some(&ODS),
69 Format::Odp => Some(&ODP),
70 }
71}
72
73static OGG_VORBIS: OggHandler = OggHandler::VORBIS;
74static OPUS: OggHandler = OggHandler::OPUS;
75static OGG_FLAC: OggHandler = OggHandler::FLAC;
76static MP4: Mp4Handler = Mp4Handler::MP4;
77static M4A: Mp4Handler = Mp4Handler::M4A;
78static HEIF: HeifHandler = HeifHandler::HEIF;
79static AVIF: HeifHandler = HeifHandler::AVIF;
80static DOCX: OoxmlHandler = OoxmlHandler::DOCX;
81static XLSX: OoxmlHandler = OoxmlHandler::XLSX;
82static PPTX: OoxmlHandler = OoxmlHandler::PPTX;
83static ODT: OdfHandler = OdfHandler::ODT;
84static ODS: OdfHandler = OdfHandler::ODS;
85static ODP: OdfHandler = OdfHandler::ODP;
86
87#[must_use]
89pub fn supported_formats() -> Vec<Format> {
90 [
91 Format::Jpeg,
92 Format::Png,
93 Format::Webp,
94 Format::Pdf,
95 Format::Tiff,
96 Format::Gif,
97 Format::Svg,
98 Format::Jxl,
99 Format::Flac,
100 Format::Wav,
101 Format::Mp3,
102 Format::Ogg,
103 Format::Opus,
104 Format::OggFlac,
105 Format::Mp4,
106 Format::M4a,
107 Format::Heif,
108 Format::Avif,
109 Format::Docx,
110 Format::Xlsx,
111 Format::Pptx,
112 Format::Odt,
113 Format::Ods,
114 Format::Odp,
115 ]
116 .into_iter()
117 .filter(|f| handler_for(*f).is_some())
118 .collect()
119}
120
121#[cfg(test)]
122mod tests {
123 #![allow(clippy::expect_used)]
124
125 use super::*;
126
127 #[test]
128 fn a_handler_is_registered_for_its_own_format() {
129 for format in supported_formats() {
130 let handler = handler_for(format).expect("listed as supported");
131 assert_eq!(handler.format(), format);
132 assert_eq!(
133 handler.name(),
134 format.id(),
135 "the handler name is the format id, because both appear in JSON output"
136 );
137 }
138 }
139
140 #[test]
141 fn every_shipped_format_has_a_handler() {
142 for format in [
147 Format::Jpeg,
148 Format::Png,
149 Format::Webp,
150 Format::Pdf,
151 Format::Tiff,
152 Format::Gif,
153 Format::Svg,
154 Format::Jxl,
155 Format::Flac,
156 Format::Wav,
157 Format::Mp3,
158 Format::Ogg,
159 Format::Opus,
160 Format::OggFlac,
161 Format::Mp4,
162 Format::M4a,
163 Format::Docx,
164 Format::Xlsx,
165 Format::Pptx,
166 Format::Odt,
167 Format::Ods,
168 Format::Odp,
169 ] {
170 assert!(handler_for(format).is_some(), "{format} has no handler");
171 }
172 }
173}