1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[allow(non_camel_case_types)]
9pub enum FileType {
10 Jpeg,
12 Tiff,
13 Png,
14 Gif,
15 Bmp,
16 WebP,
17 Heif,
18 Avif,
19 Psd,
20 Jp2,
21 J2c,
22 Jxl,
23 Jxr,
24 Flif,
25 Bpg,
26 Exr,
27 Ico,
28 Jps,
29 DjVu,
31 Xcf,
32 Pcx,
33 Pict,
34 Psp,
35 Hdr,
36 Rwz,
37 Btf,
38 Mng,
39 PhotoCd,
40 Cr2,
42 Cr3,
43 Crw,
44 Nef,
45 Arw,
46 Sr2,
47 Srf,
48 Orf,
49 Rw2,
50 Dng,
51 Raf,
52 Pef,
53 Dcr,
54 Mrw,
55 Erf,
56 Fff,
57 Iiq,
58 Rwl,
59 Mef,
60 Srw,
61 X3f,
62 Gpr,
63 Arq,
64 ThreeFR,
65 Crm,
66 Mp4,
68 QuickTime,
69 Avi,
70 Mkv,
71 WebM,
72 Wmv,
73 Asf,
74 Flv,
75 Mxf,
76 Czi,
77 M2ts,
78 Mpeg,
79 ThreeGP,
80 RealMedia,
81 R3d,
82 Dvb,
83 Lrv,
84 Mqv,
85 F4v,
86 Wtv,
87 DvrMs,
88 Mp3,
90 Flac,
91 Ogg,
92 Wav,
93 Aiff,
94 Aac,
95 Opus,
96 Mpc,
97 Ape,
98 WavPack,
99 Ofr,
100 Dsf,
101 Audible,
102 RealAudio,
103 Wma,
104 M4a,
105 Dss,
106 Pdf,
108 PostScript,
109 Doc,
110 Docx,
111 Xls,
112 Xlsx,
113 Ppt,
114 Pptx,
115 Numbers,
116 Pages,
117 Key,
118 InDesign,
119 Rtf,
120 Zip,
122 Rar,
123 SevenZ,
124 Gzip,
125 Xmp,
127 Mie,
128 Exv,
129 Vrd,
130 Dr4,
131 Icc,
132 Html,
133 Exe,
134 Font,
135 Swf,
136 Dicom,
137 Fits,
138 Mrc,
140 Moi,
141 MacOs,
142 Json,
143 Pcap,
144 Pcapng,
145 Svg,
146 Pgf,
148 Xisf,
149 Torrent,
150 Mobi,
151 SonyPmp,
152 Plist,
154 Aae,
155 KyoceraRaw,
156 Lfp,
158 PortableFloatMap,
160 Fpf,
162 Ods,
164 Odt,
165 Odp,
166 Odg,
167 Odf,
168 Odb,
169 Odi,
170 Odc,
171 Eip,
173 Lif,
175 Txt,
177 Csv,
178 Vcard,
179 Ics,
180 Url,
181 Lnk,
182 Ppm,
183 Dpx,
184 Ram,
185 Miff,
187 Tnef,
188 Wpg,
189 Dv,
190 Itc,
191 Iso,
192 Afm,
193 Pfa,
194 Pfb,
195 Dfont,
196 Xml,
197 Inx,
198 Eps,
199}
200
201#[derive(Debug, Clone, Copy, PartialEq, Eq)]
203pub enum Support {
204 Read,
205 ReadWrite,
206 ReadWriteCreate,
207}
208
209impl FileType {
210 pub fn description(self) -> &'static str {
212 match self {
213 FileType::Jpeg => "JPEG image",
215 FileType::Tiff => "TIFF image",
216 FileType::Png => "PNG image",
217 FileType::Gif => "GIF image",
218 FileType::Bmp => "BMP image",
219 FileType::WebP => "WebP image",
220 FileType::Heif => "HEIF/HEIC image",
221 FileType::Avif => "AVIF image",
222 FileType::Psd => "Adobe Photoshop Document",
223 FileType::Jp2 => "JPEG 2000 image",
224 FileType::J2c => "JPEG 2000 Codestream",
225 FileType::Jxl => "JPEG XL image",
226 FileType::Jxr => "JPEG XR / HD Photo",
227 FileType::Flif => "Free Lossless Image Format",
228 FileType::Bpg => "Better Portable Graphics",
229 FileType::Exr => "OpenEXR image",
230 FileType::Ico => "Windows Icon",
231 FileType::Jps => "JPEG Stereo image",
232 FileType::DjVu => "DjVu document",
234 FileType::Xcf => "GIMP image",
235 FileType::Pcx => "PCX image",
236 FileType::Pict => "Apple PICT",
237 FileType::Psp => "Paint Shop Pro image",
238 FileType::Pgf => "Progressive Graphics File",
239 FileType::Xisf => "PixInsight XISF image",
240 FileType::Torrent => "BitTorrent descriptor",
241 FileType::Mobi => "Mobipocket Book",
242 FileType::SonyPmp => "Sony PMP video",
243 FileType::Plist => "PLIST",
244 FileType::Aae => "AAE",
245 FileType::KyoceraRaw => "Kyocera Contax N RAW",
246 FileType::Lfp => "LFP",
247 FileType::PortableFloatMap => "Portable Float Map",
248 FileType::Hdr => "Radiance HDR",
249 FileType::Rwz => "Rawzor compressed image",
250 FileType::Btf => "BigTIFF image",
251 FileType::Mng => "MNG animation",
252 FileType::PhotoCd => "Kodak Photo CD",
253 FileType::Cr2 => "Canon CR2 RAW",
255 FileType::Cr3 => "Canon CR3 RAW",
256 FileType::Crw => "Canon CRW RAW",
257 FileType::Nef => "Nikon NEF RAW",
258 FileType::Arw => "Sony ARW RAW",
259 FileType::Sr2 => "Sony SR2 RAW",
260 FileType::Srf => "Sony SRF RAW",
261 FileType::Orf => "Olympus ORF RAW",
262 FileType::Rw2 => "Panasonic RW2 RAW",
263 FileType::Dng => "Adobe Digital Negative",
264 FileType::Raf => "Fujifilm RAF RAW",
265 FileType::Pef => "Pentax PEF RAW",
266 FileType::Dcr => "Kodak DCR RAW",
267 FileType::Mrw => "Minolta MRW RAW",
268 FileType::Erf => "Epson ERF RAW",
269 FileType::Fff => "Hasselblad FFF RAW",
270 FileType::Iiq => "Phase One IIQ RAW",
271 FileType::Rwl => "Leica RWL RAW",
272 FileType::Mef => "Mamiya MEF RAW",
273 FileType::Srw => "Samsung SRW RAW",
274 FileType::X3f => "Sigma X3F RAW",
275 FileType::Gpr => "GoPro GPR RAW",
276 FileType::Arq => "Sony ARQ RAW",
277 FileType::ThreeFR => "Hasselblad 3FR RAW",
278 FileType::Crm => "Canon Cinema RAW",
279 FileType::Mp4 => "MP4 video",
281 FileType::QuickTime => "QuickTime video",
282 FileType::Avi => "AVI",
283 FileType::Mkv => "Matroska video",
284 FileType::WebM => "WebM video",
285 FileType::Wmv => "Windows Media Video",
286 FileType::Asf => "Advanced Systems Format",
287 FileType::Flv => "Flash Video",
288 FileType::Mxf => "Material Exchange Format",
289 FileType::Czi => "CZI",
290 FileType::M2ts => "MPEG-2 Transport Stream",
291 FileType::Mpeg => "MPEG video",
292 FileType::ThreeGP => "3GPP multimedia",
293 FileType::RealMedia => "RealMedia",
294 FileType::R3d => "Redcode RAW video",
295 FileType::Dvb => "Digital Video Broadcasting",
296 FileType::Lrv => "GoPro Low-Res Video",
297 FileType::Mqv => "Sony Movie",
298 FileType::F4v => "Adobe Flash Video",
299 FileType::Wtv => "Windows Recorded TV",
300 FileType::DvrMs => "Microsoft DVR",
301 FileType::Mp3 => "MP3 audio",
303 FileType::Flac => "FLAC audio",
304 FileType::Ogg => "Ogg Vorbis audio",
305 FileType::Wav => "WAV audio",
306 FileType::Aiff => "AIFF",
307 FileType::Aac => "AAC audio",
308 FileType::Opus => "Opus audio",
309 FileType::Mpc => "Musepack audio",
310 FileType::Ape => "Monkey's Audio",
311 FileType::WavPack => "WavPack audio",
312 FileType::Ofr => "OptimFROG audio",
313 FileType::Dsf => "DSD Stream File",
314 FileType::Audible => "Audible audiobook",
315 FileType::RealAudio => "RealAudio",
316 FileType::Wma => "Windows Media Audio",
317 FileType::M4a => "MPEG-4 Audio",
318 FileType::Dss => "DSS",
319 FileType::Pdf => "PDF document",
321 FileType::PostScript => "PostScript",
322 FileType::Doc => "Microsoft Word (legacy)",
323 FileType::Docx => "Microsoft Word",
324 FileType::Xls => "Microsoft Excel (legacy)",
325 FileType::Xlsx => "Microsoft Excel",
326 FileType::Ppt => "Microsoft PowerPoint (legacy)",
327 FileType::Pptx => "Microsoft PowerPoint",
328 FileType::Numbers => "Apple Numbers",
329 FileType::Pages => "Apple Pages",
330 FileType::Key => "Apple Keynote",
331 FileType::InDesign => "Adobe InDesign",
332 FileType::Rtf => "Rich Text Format",
333 FileType::Zip => "ZIP archive",
335 FileType::Rar => "RAR archive",
336 FileType::SevenZ => "7-Zip archive",
337 FileType::Gzip => "GZIP",
338 FileType::Xmp => "XMP sidecar",
340 FileType::Mie => "MIE metadata",
341 FileType::Exv => "Exiv2 metadata",
342 FileType::Vrd => "VRD",
343 FileType::Dr4 => "DR4",
344 FileType::Icc => "ICC color profile",
345 FileType::Html => "HTML document",
346 FileType::Exe => "Windows executable",
347 FileType::Font => "Font file",
348 FileType::Swf => "Shockwave Flash",
349 FileType::Dicom => "DICOM medical image",
350 FileType::Fits => "FITS astronomical image",
351 FileType::Mrc => "MRC image",
352 FileType::Moi => "MOI",
353 FileType::MacOs => "MacOS",
354 FileType::Json => "JSON",
355 FileType::Pcap => "PCAP",
356 FileType::Pcapng => "PCAPNG",
357 FileType::Svg => "SVG",
358 FileType::Fpf => "FPF",
359 FileType::Ods => "ODS",
360 FileType::Odt => "ODT",
361 FileType::Odp => "ODP",
362 FileType::Odg => "ODG",
363 FileType::Odf => "ODF",
364 FileType::Odb => "ODB",
365 FileType::Odi => "ODI",
366 FileType::Odc => "ODC",
367 FileType::Eip => "EIP",
368 FileType::Lif => "Leica Image Format",
369 FileType::Txt => "Text",
370 FileType::Csv => "Comma-Separated Values",
371 FileType::Vcard => "vCard",
372 FileType::Ics => "iCalendar",
373 FileType::Url => "Windows URL Shortcut",
374 FileType::Lnk => "Windows Shortcut",
375 FileType::Ppm => "Portable Pixel Map",
376 FileType::Dpx => "Digital Picture Exchange",
377 FileType::Ram => "Real Audio Metadata",
378 FileType::Miff => "Magick Image File Format",
379 FileType::Tnef => "Transport Neutral Encapsulation Format",
380 FileType::Wpg => "WordPerfect Graphics",
381 FileType::Dv => "Digital Video",
382 FileType::Itc => "iTunes Cover Flow",
383 FileType::Iso => "ISO 9660 disk image",
384 FileType::Afm => "Adobe Font Metrics",
385 FileType::Pfa => "PostScript Font ASCII",
386 FileType::Pfb => "PostScript Font Binary",
387 FileType::Dfont => "Macintosh Font",
388 FileType::Xml => "Extensible Markup Language",
389 FileType::Inx => "Adobe InDesign Interchange",
390 FileType::Eps => "Encapsulated PostScript",
391 }
392 }
393
394 pub fn code(self) -> &'static str {
397 match self {
398 FileType::Jpeg => "JPEG",
399 FileType::Tiff => "TIFF",
400 FileType::Png => "PNG",
401 FileType::Gif => "GIF",
402 FileType::Bmp => "BMP",
403 FileType::WebP => "WEBP",
404 FileType::Heif => "HEIF",
405 FileType::Avif => "AVIF",
406 FileType::Psd => "PSD",
407 FileType::Jp2 => "JP2",
408 FileType::J2c => "J2C",
409 FileType::Jxl => "JXL",
410 FileType::Jxr => "JXR",
411 FileType::Flif => "FLIF",
412 FileType::Bpg => "BPG",
413 FileType::Exr => "EXR",
414 FileType::Ico => "ICO",
415 FileType::Jps => "JPS",
416 FileType::DjVu => "DJVU",
417 FileType::Xcf => "XCF",
418 FileType::Pcx => "PCX",
419 FileType::Pict => "PICT",
420 FileType::Psp => "PSP",
421 FileType::Pgf => "PGF",
422 FileType::Xisf => "XISF",
423 FileType::Torrent => "Torrent",
424 FileType::Mobi => "MOBI",
425 FileType::SonyPmp => "PMP",
426 FileType::Plist => "PLIST",
427 FileType::Aae => "AAE",
428 FileType::KyoceraRaw => "RAW",
429 FileType::Lfp => "LFP",
430 FileType::PortableFloatMap => "PFM",
431 FileType::Hdr => "HDR",
432 FileType::Rwz => "RWZ",
433 FileType::Btf => "BTF",
434 FileType::Mng => "MNG",
435 FileType::PhotoCd => "PCD",
436 FileType::Cr2 => "CR2",
437 FileType::Cr3 => "CR3",
438 FileType::Crw => "CRW",
439 FileType::Nef => "NEF",
440 FileType::Arw => "ARW",
441 FileType::Sr2 => "SR2",
442 FileType::Srf => "SRF",
443 FileType::Orf => "ORF",
444 FileType::Rw2 => "RW2",
445 FileType::Dng => "DNG",
446 FileType::Raf => "RAF",
447 FileType::Pef => "PEF",
448 FileType::Dcr => "DCR",
449 FileType::Mrw => "MRW",
450 FileType::Erf => "ERF",
451 FileType::Fff => "FFF",
452 FileType::Iiq => "IIQ",
453 FileType::Rwl => "RWL",
454 FileType::Mef => "MEF",
455 FileType::Srw => "SRW",
456 FileType::X3f => "X3F",
457 FileType::Gpr => "GPR",
458 FileType::Arq => "ARQ",
459 FileType::ThreeFR => "3FR",
460 FileType::Crm => "CRM",
461 FileType::Mp4 => "MP4",
462 FileType::QuickTime => "MOV",
463 FileType::Avi => "AVI",
464 FileType::Mkv => "MKV",
465 FileType::WebM => "WEBM",
466 FileType::Wmv => "WMV",
467 FileType::Asf => "ASF",
468 FileType::Flv => "FLV",
469 FileType::Mxf => "MXF",
470 FileType::Czi => "CZI",
471 FileType::M2ts => "M2TS",
472 FileType::Mpeg => "MPEG",
473 FileType::ThreeGP => "3GP",
474 FileType::RealMedia => "RM",
475 FileType::R3d => "R3D",
476 FileType::Dvb => "DVB",
477 FileType::Lrv => "LRV",
478 FileType::Mqv => "MQV",
479 FileType::F4v => "F4V",
480 FileType::Wtv => "WTV",
481 FileType::DvrMs => "DVR-MS",
482 FileType::Mp3 => "MP3",
483 FileType::Flac => "FLAC",
484 FileType::Ogg => "OGG",
485 FileType::Wav => "WAV",
486 FileType::Aiff => "AIFF",
487 FileType::Aac => "AAC",
488 FileType::Opus => "OPUS",
489 FileType::Mpc => "MPC",
490 FileType::Ape => "APE",
491 FileType::WavPack => "WV",
492 FileType::Ofr => "OFR",
493 FileType::Dsf => "DSF",
494 FileType::Audible => "AA",
495 FileType::RealAudio => "RA",
496 FileType::Wma => "WMA",
497 FileType::M4a => "M4A",
498 FileType::Dss => "DSS",
499 FileType::Pdf => "PDF",
500 FileType::PostScript => "PS",
501 FileType::Doc => "DOC",
502 FileType::Docx => "DOCX",
503 FileType::Xls => "XLS",
504 FileType::Xlsx => "XLSX",
505 FileType::Ppt => "PPT",
506 FileType::Pptx => "PPTX",
507 FileType::Numbers => "NUMBERS",
508 FileType::Pages => "PAGES",
509 FileType::Key => "KEY",
510 FileType::InDesign => "INDD",
511 FileType::Rtf => "RTF",
512 FileType::Zip => "ZIP",
513 FileType::Rar => "RAR",
514 FileType::SevenZ => "7Z",
515 FileType::Gzip => "GZIP",
516 FileType::Xmp => "XMP",
517 FileType::Mie => "MIE",
518 FileType::Exv => "EXV",
519 FileType::Vrd => "VRD",
520 FileType::Dr4 => "DR4",
521 FileType::Icc => "ICC",
522 FileType::Html => "HTML",
523 FileType::Exe => "EXE",
524 FileType::Font => "TTF",
525 FileType::Swf => "SWF",
526 FileType::Dicom => "DICOM",
527 FileType::Fits => "FITS",
528 FileType::Mrc => "MRC",
529 FileType::Moi => "MOI",
530 FileType::MacOs => "MacOS",
531 FileType::Json => "JSON",
532 FileType::Pcap => "PCAP",
533 FileType::Pcapng => "PCAPNG",
534 FileType::Svg => "SVG",
535 FileType::Fpf => "FPF",
536 FileType::Ods => "ODS",
537 FileType::Odt => "ODT",
538 FileType::Odp => "ODP",
539 FileType::Odg => "ODG",
540 FileType::Odf => "ODF",
541 FileType::Odb => "ODB",
542 FileType::Odi => "ODI",
543 FileType::Odc => "ODC",
544 FileType::Eip => "EIP",
545 FileType::Lif => "LIF",
546 FileType::Txt => "TXT",
547 FileType::Csv => "CSV",
548 FileType::Vcard => "VCard",
549 FileType::Ics => "ICS",
550 FileType::Url => "URL",
551 FileType::Lnk => "LNK",
552 FileType::Ppm => "PPM",
553 FileType::Dpx => "DPX",
554 FileType::Ram => "RAM",
555 FileType::Miff => "MIFF",
556 FileType::Tnef => "TNEF",
557 FileType::Wpg => "WPG",
558 FileType::Dv => "DV",
559 FileType::Itc => "ITC",
560 FileType::Iso => "ISO",
561 FileType::Afm => "AFM",
562 FileType::Pfa => "PFA",
563 FileType::Pfb => "PFB",
564 FileType::Dfont => "DFONT",
565 FileType::Xml => "XML",
566 FileType::Inx => "INX",
567 FileType::Eps => "EPS",
568 }
569 }
570
571 pub fn mime_type(self) -> &'static str {
573 match self {
574 FileType::Jpeg => "image/jpeg",
575 FileType::Tiff => "image/tiff",
576 FileType::Btf => "image/x-tiff-big",
577 FileType::Png => "image/png",
578 FileType::Gif => "image/gif",
579 FileType::Bmp => "image/bmp",
580 FileType::WebP => "image/webp",
581 FileType::Heif => "image/heif",
582 FileType::Avif => "image/avif",
583 FileType::Psd => "application/vnd.adobe.photoshop",
584 FileType::Jp2 => "image/jp2",
585 FileType::J2c => "image/x-j2c",
586 FileType::Jxl => "image/jxl",
587 FileType::Jxr => "image/jxr",
588 FileType::Flif => "image/flif",
589 FileType::Bpg => "image/bpg",
590 FileType::Exr => "image/x-exr",
591 FileType::Ico => "image/x-icon",
592 FileType::Jps => "image/x-jps",
593 FileType::DjVu => "image/vnd.djvu",
594 FileType::Xcf => "image/x-xcf",
595 FileType::Pcx => "image/pcx",
596 FileType::Pict => "image/pict",
597 FileType::Psp => "image/x-paintshoppro",
598 FileType::Hdr => "image/vnd.radiance",
599 FileType::Rwz => "image/x-rawzor",
600 FileType::Mng => "video/x-mng",
601 FileType::PhotoCd => "image/x-photo-cd",
602 FileType::Cr2 => "image/x-canon-cr2",
604 FileType::Cr3 | FileType::Crm => "image/x-canon-cr3",
605 FileType::Crw => "image/x-canon-crw",
606 FileType::Nef => "image/x-nikon-nef",
607 FileType::Arw | FileType::Arq => "image/x-sony-arw",
608 FileType::Sr2 => "image/x-sony-sr2",
609 FileType::Srf => "image/x-sony-srf",
610 FileType::Orf => "image/x-olympus-orf",
611 FileType::Rw2 => "image/x-panasonic-rw2",
612 FileType::Dng | FileType::Gpr => "image/x-adobe-dng",
613 FileType::Raf => "image/x-fujifilm-raf",
614 FileType::Pef => "image/x-pentax-pef",
615 FileType::Dcr => "image/x-kodak-dcr",
616 FileType::Mrw => "image/x-minolta-mrw",
617 FileType::Erf => "image/x-epson-erf",
618 FileType::Fff | FileType::ThreeFR => "image/x-hasselblad-fff",
619 FileType::Iiq => "image/x-raw",
620 FileType::Rwl => "image/x-leica-rwl",
621 FileType::Mef => "image/x-mamiya-mef",
622 FileType::Srw => "image/x-samsung-srw",
623 FileType::X3f => "image/x-sigma-x3f",
624 FileType::Mp4 | FileType::F4v => "video/mp4",
626 FileType::QuickTime | FileType::Mqv => "video/quicktime",
627 FileType::Avi => "video/x-msvideo",
628 FileType::Mkv => "video/x-matroska",
629 FileType::WebM => "video/webm",
630 FileType::Wmv => "video/x-ms-wmv",
631 FileType::Asf => "video/x-ms-asf",
632 FileType::Flv => "video/x-flv",
633 FileType::Mxf => "application/mxf",
634 FileType::Czi => "image/x-zeiss-czi",
635 FileType::M2ts => "video/m2ts",
636 FileType::Mpeg => "video/mpeg",
637 FileType::ThreeGP => "video/3gpp",
638 FileType::RealMedia => "application/vnd.rn-realmedia",
639 FileType::R3d => "video/x-red-r3d",
640 FileType::Dvb => "video/dvb",
641 FileType::Lrv => "video/mp4",
642 FileType::Wtv => "video/x-ms-wtv",
643 FileType::DvrMs => "video/x-ms-dvr",
644 FileType::Mp3 => "audio/mpeg",
646 FileType::Flac => "audio/flac",
647 FileType::Ogg | FileType::Opus => "audio/ogg",
648 FileType::Wav => "audio/x-wav",
649 FileType::Aiff => "audio/x-aiff",
650 FileType::Aac => "audio/aac",
651 FileType::Mpc => "audio/x-musepack",
652 FileType::Ape => "audio/x-monkeys-audio",
653 FileType::WavPack => "audio/x-wavpack",
654 FileType::Ofr => "audio/x-ofr",
655 FileType::Dsf => "audio/dsf",
656 FileType::Audible => "audio/audible",
657 FileType::RealAudio => "audio/x-pn-realaudio",
658 FileType::Wma => "audio/x-ms-wma",
659 FileType::M4a => "audio/mp4",
660 FileType::Dss => "audio/x-dss",
661 FileType::Pdf => "application/pdf",
663 FileType::PostScript => "application/postscript",
664 FileType::Doc => "application/msword",
665 FileType::Docx => {
666 "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
667 }
668 FileType::Xls => "application/vnd.ms-excel",
669 FileType::Xlsx => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
670 FileType::Ppt => "application/vnd.ms-powerpoint",
671 FileType::Pptx => {
672 "application/vnd.openxmlformats-officedocument.presentationml.presentation"
673 }
674 FileType::Numbers => "application/x-iwork-numbers-sffnumbers",
675 FileType::Pages => "application/x-iwork-pages-sffpages",
676 FileType::Key => "application/x-iwork-keynote-sffkey",
677 FileType::InDesign => "application/x-indesign",
678 FileType::Rtf => "text/rtf",
679 FileType::Zip => "application/zip",
681 FileType::Rar => "application/x-rar-compressed",
682 FileType::SevenZ => "application/x-7z-compressed",
683 FileType::Gzip => "application/x-gzip",
684 FileType::Xmp => "application/rdf+xml",
686 FileType::Mie => "application/x-mie",
687 FileType::Exv => "application/x-exv",
688 FileType::Vrd => "application/octet-stream",
689 FileType::Dr4 => "application/octet-stream",
690 FileType::Icc => "application/vnd.iccprofile",
691 FileType::Html => "text/html",
692 FileType::Exe => "application/x-dosexec",
693 FileType::Font => "application/font-ttf",
694 FileType::Swf => "application/x-shockwave-flash",
695 FileType::Dicom => "application/dicom",
696 FileType::Fits => "image/fits",
697 FileType::Mrc => "image/x-mrc",
698 FileType::Moi => "application/octet-stream",
699 FileType::MacOs => "application/unknown",
700 FileType::Json => "application/json",
701 FileType::Pcap => "application/vnd.tcpdump.pcap",
702 FileType::Pcapng => "application/vnd.tcpdump.pcap",
703 FileType::Svg => "image/svg+xml",
704 FileType::Pgf => "image/pgf",
705 FileType::Xisf => "image/x-xisf",
706 FileType::Torrent => "application/x-bittorrent",
707 FileType::Mobi => "application/x-mobipocket-ebook",
708 FileType::SonyPmp => "image/x-sony-pmp",
709 FileType::Plist => "application/x-plist",
710 FileType::Aae => "application/vnd.apple.photos",
711 FileType::KyoceraRaw => "image/x-raw",
712 FileType::Lfp => "image/x-lytro-lfp",
713 FileType::PortableFloatMap => "image/x-pfm",
714 FileType::Fpf => "image/x-flir-fpf",
715 FileType::Ods => "application/vnd.oasis.opendocument.spreadsheet",
716 FileType::Odt => "application/vnd.oasis.opendocument.text",
717 FileType::Odp => "application/vnd.oasis.opendocument.presentation",
718 FileType::Odg => "application/vnd.oasis.opendocument.graphics",
719 FileType::Odf => "application/vnd.oasis.opendocument.formula",
720 FileType::Odb => "application/vnd.oasis.opendocument.database",
721 FileType::Odi => "application/vnd.oasis.opendocument.image",
722 FileType::Odc => "application/vnd.oasis.opendocument.chart",
723 FileType::Eip => "application/x-captureone",
724 FileType::Lif => "image/x-leica-lif",
725 FileType::Txt => "text/plain",
726 FileType::Csv => "text/csv",
727 FileType::Vcard => "text/vcard",
728 FileType::Ics => "text/calendar",
729 FileType::Url => "application/x-mswinurl",
730 FileType::Lnk => "application/octet-stream",
731 FileType::Ppm => "image/x-portable-pixmap",
732 FileType::Dpx => "image/x-dpx",
733 FileType::Ram => "audio/x-pn-realaudio",
734 FileType::Miff => "application/x-magick-image",
735 FileType::Tnef => "application/vnd.ms-tnef",
736 FileType::Wpg => "image/x-wpg",
737 FileType::Dv => "video/x-dv",
738 FileType::Itc => "application/itunes",
739 FileType::Iso => "application/x-iso9660-image",
740 FileType::Afm => "application/x-font-afm",
741 FileType::Pfa => "application/x-font-type1",
742 FileType::Pfb => "application/x-font-type1",
743 FileType::Dfont => "application/x-dfont",
744 FileType::Xml => "application/xml",
745 FileType::Inx => "application/x-indesign-interchange",
746 FileType::Eps => "application/postscript",
747 }
748 }
749
750 pub fn extensions(self) -> &'static [&'static str] {
752 match self {
753 FileType::Jpeg => &["jpg", "jpeg", "jpe", "jif", "jfif"],
754 FileType::Tiff => &["tif", "tiff"],
755 FileType::Png => &["png"],
756 FileType::Gif => &["gif"],
757 FileType::Bmp => &["bmp", "dib"],
758 FileType::WebP => &["webp"],
759 FileType::Heif => &["heif", "heic", "hif"],
760 FileType::Avif => &["avif"],
761 FileType::Psd => &["psd", "psb", "psdt"],
762 FileType::Jp2 => &["jp2", "jpf", "jpm", "jpx", "jph"],
763 FileType::J2c => &["j2c", "j2k", "jpc"],
764 FileType::Jxl => &["jxl"],
765 FileType::Jxr => &["jxr", "hdp", "wdp"],
766 FileType::Flif => &["flif"],
767 FileType::Bpg => &["bpg"],
768 FileType::Exr => &["exr"],
769 FileType::Ico => &["ico", "cur"],
770 FileType::Jps => &["jps"],
771 FileType::DjVu => &["djvu", "djv"],
772 FileType::Xcf => &["xcf"],
773 FileType::Pcx => &["pcx"],
774 FileType::Pict => &["pict", "pct"],
775 FileType::Psp => &["psp", "pspimage"],
776 FileType::Hdr => &["hdr"],
777 FileType::Rwz => &["rwz"],
778 FileType::Btf => &["btf"],
779 FileType::Mng => &["mng", "jng"],
780 FileType::PhotoCd => &["pcd"],
781 FileType::Cr2 => &["cr2"],
783 FileType::Cr3 => &["cr3"],
784 FileType::Crw => &["crw", "ciff"],
785 FileType::Nef => &["nef", "nrw"],
786 FileType::Arw => &["arw"],
787 FileType::Sr2 => &["sr2"],
788 FileType::Srf => &["srf"],
789 FileType::Orf => &["orf", "ori"],
790 FileType::Rw2 => &["rw2"],
791 FileType::Dng => &["dng"],
792 FileType::Raf => &["raf"],
793 FileType::Pef => &["pef"],
794 FileType::Dcr => &["dcr"],
795 FileType::Mrw => &["mrw"],
796 FileType::Erf => &["erf"],
797 FileType::Fff => &["fff"],
798 FileType::Iiq => &["iiq"],
799 FileType::Rwl => &["rwl"],
800 FileType::Mef => &["mef"],
801 FileType::Srw => &["srw"],
802 FileType::X3f => &["x3f"],
803 FileType::Gpr => &["gpr"],
804 FileType::Arq => &["arq"],
805 FileType::ThreeFR => &["3fr"],
806 FileType::Crm => &["crm"],
807 FileType::Mp4 => &["mp4", "m4v"],
809 FileType::QuickTime => &["mov", "qt"],
810 FileType::Avi => &["avi"],
811 FileType::Mkv => &["mkv", "mks"],
812 FileType::WebM => &["webm"],
813 FileType::Wmv => &["wmv"],
814 FileType::Asf => &["asf"],
815 FileType::Flv => &["flv"],
816 FileType::Mxf => &["mxf"],
817 FileType::Czi => &["czi"],
818 FileType::M2ts => &["mts", "m2ts", "m2t", "ts"],
819 FileType::Mpeg => &["mpg", "mpeg", "m2v", "mpv"],
820 FileType::ThreeGP => &["3gp", "3gpp", "3g2", "3gp2"],
821 FileType::RealMedia => &["rm", "rv", "rmvb"],
822 FileType::R3d => &["r3d"],
823 FileType::Dvb => &["dvb"],
824 FileType::Lrv => &["lrv", "lrf"],
825 FileType::Mqv => &["mqv"],
826 FileType::F4v => &["f4v", "f4a", "f4b", "f4p"],
827 FileType::Wtv => &["wtv"],
828 FileType::DvrMs => &["dvr-ms"],
829 FileType::Mp3 => &["mp3"],
831 FileType::Flac => &["flac"],
832 FileType::Ogg => &["ogg", "oga", "ogv"],
833 FileType::Wav => &["wav"],
834 FileType::Aiff => &["aiff", "aif", "aifc"],
835 FileType::Aac => &["aac"],
836 FileType::Opus => &["opus"],
837 FileType::Mpc => &["mpc"],
838 FileType::Ape => &["ape"],
839 FileType::WavPack => &["wv", "wvp"],
840 FileType::Ofr => &["ofr"],
841 FileType::Dsf => &["dsf"],
842 FileType::Audible => &["aa", "aax"],
843 FileType::RealAudio => &["ra"],
844 FileType::Wma => &["wma"],
845 FileType::M4a => &["m4a", "m4b", "m4p"],
846 FileType::Dss => &["dss"],
847 FileType::Pdf => &["pdf"],
849 FileType::PostScript => &["ps", "eps", "epsf"],
850 FileType::Doc => &["doc", "dot"],
851 FileType::Docx => &["docx", "docm"],
852 FileType::Xls => &["xls", "xlt"],
853 FileType::Xlsx => &["xlsx", "xlsm", "xlsb"],
854 FileType::Ppt => &["ppt", "pps", "pot"],
855 FileType::Pptx => &["pptx", "pptm"],
856 FileType::Numbers => &["numbers", "nmbtemplate"],
857 FileType::Pages => &["pages"],
858 FileType::Key => &["key", "kth"],
859 FileType::InDesign => &["indd", "ind", "indt"],
860 FileType::Rtf => &["rtf"],
861 FileType::Zip => &["zip"],
863 FileType::Rar => &["rar"],
864 FileType::SevenZ => &["7z"],
865 FileType::Gzip => &["gz", "gzip"],
866 FileType::Xmp => &["xmp"],
868 FileType::Mie => &["mie"],
869 FileType::Exv => &["exv"],
870 FileType::Vrd => &["vrd"],
871 FileType::Dr4 => &["dr4"],
872 FileType::Icc => &["icc", "icm"],
873 FileType::Html => &["html", "htm", "xhtml", "svg"],
874 FileType::Exe => &["exe", "dll", "elf", "so", "dylib", "a", "macho", "o"],
875 FileType::Font => &["ttf", "otf", "woff", "woff2", "ttc"],
876 FileType::Swf => &["swf"],
877 FileType::Dicom => &["dcm"],
878 FileType::Fits => &["fits", "fit", "fts"],
879 FileType::Mrc => &["mrc"],
880 FileType::Moi => &["moi"],
881 FileType::MacOs => &["macos"],
882 FileType::Json => &["json"],
883 FileType::Pcap => &["pcap", "cap"],
884 FileType::Pcapng => &["pcapng", "ntar"],
885 FileType::Svg => &["svg"],
886 FileType::Pgf => &["pgf"],
887 FileType::Xisf => &["xisf"],
888 FileType::Torrent => &["torrent"],
889 FileType::Mobi => &["mobi", "azw", "azw3"],
890 FileType::SonyPmp => &["pmp"],
891 FileType::Plist => &["plist"],
892 FileType::Aae => &["aae"],
893 FileType::KyoceraRaw => &["raw"],
894 FileType::PortableFloatMap => &["pfm"],
895 FileType::Fpf => &["fpf"],
896 FileType::Ods => &["ods"],
897 FileType::Odt => &["odt"],
898 FileType::Odp => &["odp"],
899 FileType::Odg => &["odg"],
900 FileType::Odf => &["odf"],
901 FileType::Odb => &["odb"],
902 FileType::Odi => &["odi"],
903 FileType::Odc => &["odc"],
904 FileType::Lfp => &["lfp", "lfr"],
905 FileType::Eip => &["eip"],
906 FileType::Lif => &["lif"],
907 FileType::Txt => &["txt", "log", "igc"],
908 FileType::Csv => &["csv"],
909 FileType::Vcard => &["vcf", "vcard"],
910 FileType::Ics => &["ics"],
911 FileType::Url => &["url"],
912 FileType::Lnk => &["lnk"],
913 FileType::Ppm => &["ppm"],
914 FileType::Dpx => &["dpx"],
915 FileType::Ram => &["ram"],
916 FileType::Miff => &["miff", "mif"],
917 FileType::Tnef => &["tnef"],
918 FileType::Wpg => &["wpg"],
919 FileType::Dv => &["dv"],
920 FileType::Itc => &["itc"],
921 FileType::Iso => &["iso"],
922 FileType::Afm => &["afm", "acfm", "amfm"],
923 FileType::Pfa => &["pfa"],
924 FileType::Pfb => &["pfb"],
925 FileType::Dfont => &["dfont"],
926 FileType::Xml => &["xml"],
927 FileType::Inx => &["inx"],
928 FileType::Eps => &["eps", "epsf", "eps3", "epsi", "ept"],
929 }
930 }
931
932 pub fn support(self) -> Support {
934 match self {
935 FileType::Xmp | FileType::Mie | FileType::Exv => Support::ReadWriteCreate,
937 FileType::Jpeg
939 | FileType::Tiff
940 | FileType::Png
941 | FileType::Gif
942 | FileType::WebP
943 | FileType::Heif
944 | FileType::Avif
945 | FileType::Psd
946 | FileType::Jp2
947 | FileType::Jxl
948 | FileType::Jxr
949 | FileType::Flif
950 | FileType::Cr2
951 | FileType::Cr3
952 | FileType::Crw
953 | FileType::Nef
954 | FileType::Arw
955 | FileType::Arq
956 | FileType::Sr2
957 | FileType::Orf
958 | FileType::Rw2
959 | FileType::Dng
960 | FileType::Raf
961 | FileType::Pef
962 | FileType::Erf
963 | FileType::Fff
964 | FileType::Iiq
965 | FileType::Rwl
966 | FileType::Mef
967 | FileType::Srw
968 | FileType::X3f
969 | FileType::Gpr
970 | FileType::Crm
971 | FileType::Mp4
972 | FileType::QuickTime
973 | FileType::ThreeGP
974 | FileType::Dvb
975 | FileType::Lrv
976 | FileType::Mqv
977 | FileType::F4v
978 | FileType::Pdf
979 | FileType::PostScript
980 | FileType::InDesign
981 | FileType::Vrd
982 | FileType::Dr4
983 | FileType::Audible => Support::ReadWrite,
984 _ => Support::Read,
986 }
987 }
988
989 pub fn all() -> &'static [FileType] {
991 ALL_FILE_TYPES
992 }
993}
994
995static ALL_FILE_TYPES: &[FileType] = &[
996 FileType::Jpeg,
998 FileType::Tiff,
999 FileType::Png,
1000 FileType::Gif,
1001 FileType::Bmp,
1002 FileType::WebP,
1003 FileType::Heif,
1004 FileType::Avif,
1005 FileType::Psd,
1006 FileType::Jp2,
1007 FileType::J2c,
1008 FileType::Jxl,
1009 FileType::Jxr,
1010 FileType::Flif,
1011 FileType::Bpg,
1012 FileType::Exr,
1013 FileType::Ico,
1014 FileType::Jps,
1015 FileType::DjVu,
1017 FileType::Xcf,
1018 FileType::Pcx,
1019 FileType::Pict,
1020 FileType::Psp,
1021 FileType::Hdr,
1022 FileType::Rwz,
1023 FileType::Btf,
1024 FileType::Mng,
1025 FileType::PhotoCd,
1026 FileType::Lif,
1027 FileType::Txt,
1028 FileType::Csv,
1029 FileType::Vcard,
1030 FileType::Ics,
1031 FileType::Url,
1032 FileType::Lnk,
1033 FileType::Ppm,
1034 FileType::Dpx,
1035 FileType::Ram,
1036 FileType::Miff,
1037 FileType::Tnef,
1038 FileType::Wpg,
1039 FileType::Dv,
1040 FileType::Itc,
1041 FileType::Iso,
1042 FileType::Afm,
1043 FileType::Pfa,
1044 FileType::Pfb,
1045 FileType::Dfont,
1046 FileType::Xml,
1047 FileType::Inx,
1048 FileType::Eps,
1049 FileType::Cr2,
1051 FileType::Cr3,
1052 FileType::Crw,
1053 FileType::Nef,
1054 FileType::Arw,
1055 FileType::Sr2,
1056 FileType::Srf,
1057 FileType::Orf,
1058 FileType::Rw2,
1059 FileType::Dng,
1060 FileType::Raf,
1061 FileType::Pef,
1062 FileType::Dcr,
1063 FileType::Mrw,
1064 FileType::Erf,
1065 FileType::Fff,
1066 FileType::Iiq,
1067 FileType::Rwl,
1068 FileType::Mef,
1069 FileType::Srw,
1070 FileType::X3f,
1071 FileType::Gpr,
1072 FileType::Arq,
1073 FileType::ThreeFR,
1074 FileType::Crm,
1075 FileType::Mp4,
1077 FileType::QuickTime,
1078 FileType::Avi,
1079 FileType::Mkv,
1080 FileType::WebM,
1081 FileType::Wmv,
1082 FileType::Asf,
1083 FileType::Flv,
1084 FileType::Mxf,
1085 FileType::M2ts,
1086 FileType::Mpeg,
1087 FileType::ThreeGP,
1088 FileType::RealMedia,
1089 FileType::R3d,
1090 FileType::Dvb,
1091 FileType::Lrv,
1092 FileType::Mqv,
1093 FileType::F4v,
1094 FileType::Wtv,
1095 FileType::DvrMs,
1096 FileType::Mp3,
1098 FileType::Flac,
1099 FileType::Ogg,
1100 FileType::Wav,
1101 FileType::Aiff,
1102 FileType::Aac,
1103 FileType::Opus,
1104 FileType::Mpc,
1105 FileType::Ape,
1106 FileType::WavPack,
1107 FileType::Ofr,
1108 FileType::Dsf,
1109 FileType::Audible,
1110 FileType::RealAudio,
1111 FileType::Wma,
1112 FileType::M4a,
1113 FileType::Dss,
1114 FileType::Pdf,
1116 FileType::PostScript,
1117 FileType::Doc,
1118 FileType::Docx,
1119 FileType::Xls,
1120 FileType::Xlsx,
1121 FileType::Ppt,
1122 FileType::Pptx,
1123 FileType::Numbers,
1124 FileType::Pages,
1125 FileType::Key,
1126 FileType::InDesign,
1127 FileType::Rtf,
1128 FileType::Zip,
1130 FileType::Rar,
1131 FileType::SevenZ,
1132 FileType::Gzip,
1133 FileType::Xmp,
1135 FileType::Mie,
1136 FileType::Exv,
1137 FileType::Vrd,
1138 FileType::Dr4,
1139 FileType::Icc,
1140 FileType::Html,
1141 FileType::Exe,
1142 FileType::Font,
1143 FileType::Swf,
1144 FileType::Dicom,
1145 FileType::Fits,
1146 FileType::Mrc,
1147 FileType::Moi,
1148 FileType::MacOs,
1149 FileType::Json,
1150 FileType::Pcap,
1151 FileType::Pcapng,
1152 FileType::Svg,
1153 FileType::Pgf,
1154 FileType::Xisf,
1155 FileType::Torrent,
1156 FileType::Mobi,
1157 FileType::SonyPmp,
1158 FileType::Plist,
1159 FileType::Aae,
1160 FileType::KyoceraRaw,
1161 FileType::PortableFloatMap,
1162 FileType::Fpf,
1163 FileType::Lfp,
1164 FileType::Ods,
1166 FileType::Odt,
1167 FileType::Odp,
1168 FileType::Odg,
1169 FileType::Odf,
1170 FileType::Odb,
1171 FileType::Odi,
1172 FileType::Odc,
1173 FileType::Eip,
1175];
1176
1177pub fn detect_from_magic(header: &[u8]) -> Option<FileType> {
1179 if header.len() < 4 {
1180 return None;
1181 }
1182
1183 if header.starts_with(&[0xFF, 0xD8, 0xFF]) {
1187 return Some(FileType::Jpeg);
1188 }
1189
1190 if header.starts_with(&[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]) {
1192 return Some(FileType::Png);
1193 }
1194
1195 if header.starts_with(&[0x89, 0x4C, 0x46, 0x50, 0x0D, 0x0A, 0x1A, 0x0A]) {
1197 return Some(FileType::Lfp);
1198 }
1199
1200 if header.starts_with(b"GIF8") && header.len() >= 6 && (header[4] == b'7' || header[4] == b'9')
1202 {
1203 return Some(FileType::Gif);
1204 }
1205
1206 if header.len() >= 8
1208 && header.starts_with(b"IIII")
1209 && (header[4] == 0x04 || header[4] == 0x05)
1210 && header[5] == 0x00
1211 && header[6] == 0x04
1212 && header[7] == 0x00
1213 {
1214 return Some(FileType::Dr4);
1215 }
1216
1217 if header.starts_with(b"CANON OPTIONAL DATA\0") {
1219 return Some(FileType::Vrd);
1220 }
1221
1222 if header.len() >= 4 {
1224 let is_le =
1225 header[0] == b'I' && header[1] == b'I' && header[2] == 0x2A && header[3] == 0x00;
1226 let is_be =
1227 header[0] == b'M' && header[1] == b'M' && header[2] == 0x00 && header[3] == 0x2A;
1228 if is_le || is_be {
1229 if header.len() >= 10 && is_le && header[8] == b'C' && header[9] == b'R' {
1231 return Some(FileType::Cr2);
1232 }
1233 if header.len() >= 12 && is_le && &header[8..12] == b"IIII" {
1235 return Some(FileType::Iiq);
1236 }
1237 if header.len() >= 12 && is_be && &header[8..12] == b"MMMM" {
1238 return Some(FileType::Iiq);
1239 }
1240 if header.len() >= 4
1242 && is_le
1243 && header[0] == b'I'
1244 && header[1] == b'I'
1245 && header.len() >= 8
1246 {
1247 }
1250 return Some(FileType::Tiff);
1253 }
1254 let is_btf_le =
1256 header[0] == b'I' && header[1] == b'I' && header[2] == 0x2B && header[3] == 0x00;
1257 let is_btf_be =
1258 header[0] == b'M' && header[1] == b'M' && header[2] == 0x00 && header[3] == 0x2B;
1259 if is_btf_le || is_btf_be {
1260 return Some(FileType::Btf);
1261 }
1262 }
1263
1264 if header.starts_with(b"BM") && header.len() >= 6 {
1266 return Some(FileType::Bmp);
1267 }
1268
1269 if header.len() >= 12 && header.starts_with(b"RIFF") {
1271 match &header[8..12] {
1272 b"WEBP" => return Some(FileType::WebP),
1273 b"AVI " => return Some(FileType::Avi),
1274 b"WAVE" => return Some(FileType::Wav),
1275 _ => {}
1276 }
1277 }
1278
1279 if header.starts_with(b"8BPS") {
1281 return Some(FileType::Psd);
1282 }
1283
1284 if header.len() >= 12 && header.starts_with(&[0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20]) {
1286 return Some(FileType::Jp2);
1287 }
1288
1289 if header.starts_with(&[0xFF, 0x4F, 0xFF, 0x51]) {
1291 return Some(FileType::J2c);
1292 }
1293
1294 if header.len() >= 2 && header[0] == 0xFF && header[1] == 0x0A {
1296 return Some(FileType::Jxl);
1297 }
1298 if header.len() >= 12 && header.starts_with(&[0x00, 0x00, 0x00, 0x0C, 0x4A, 0x58, 0x4C, 0x20]) {
1299 return Some(FileType::Jxl);
1300 }
1301
1302 if header.starts_with(b"FLIF") {
1304 return Some(FileType::Flif);
1305 }
1306
1307 if header.starts_with(&[0x42, 0x50, 0x47, 0xFB]) {
1309 return Some(FileType::Bpg);
1310 }
1311
1312 if header.starts_with(&[0x76, 0x2F, 0x31, 0x01]) {
1314 return Some(FileType::Exr);
1315 }
1316
1317 if header.len() >= 4
1319 && header[0] == 0
1320 && header[1] == 0
1321 && (header[2] == 1 || header[2] == 2)
1322 && header[3] == 0
1323 {
1324 return Some(FileType::Ico);
1325 }
1326
1327 if header.len() >= 8 && header.starts_with(b"AT&TFORM") {
1329 return Some(FileType::DjVu);
1330 }
1331
1332 if header.starts_with(b"gimp xcf") {
1334 return Some(FileType::Xcf);
1335 }
1336
1337 if header.starts_with(&[0x8A, 0x4D, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]) {
1339 return Some(FileType::Mng);
1340 }
1341
1342 if header.starts_with(&[0x8B, 0x4A, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]) {
1344 return Some(FileType::Mng);
1345 }
1346
1347 if header.len() >= 10 && header.starts_with(b"#?RADIANCE") {
1349 return Some(FileType::Hdr);
1350 }
1351
1352 if header.len() >= 3
1354 && header[0] == b'P'
1355 && (header[1] == b'F' || header[1] == b'f')
1356 && header[2] == b'\n'
1357 {
1358 return Some(FileType::PortableFloatMap);
1359 }
1360
1361 if header.starts_with(b"FPF Public Image Format\0") {
1363 return Some(FileType::Fpf);
1364 }
1365
1366 if header.len() >= 15
1368 && header[0] == 0x70
1369 && header[1] == 0x00
1370 && header[2] == 0x00
1371 && header[3] == 0x00
1372 && header[8] == 0x2A
1373 && header[13] == b'<'
1374 && header[14] == 0x00
1375 {
1376 return Some(FileType::Lif);
1377 }
1378
1379 if header.starts_with(b"rawzor") {
1381 return Some(FileType::Rwz);
1382 }
1383
1384 if header.len() >= 4 && header[0] == b'I' && header[1] == b'I' && header[2] == 0xBC {
1386 return Some(FileType::Jxr);
1387 }
1388
1389 if header.len() >= 15 && header.starts_with(b"FUJIFILMCCD-RAW") {
1393 return Some(FileType::Raf);
1394 }
1395
1396 if header.len() >= 14
1398 && header[0] == b'I'
1399 && header[1] == b'I'
1400 && header[2] == 0x1A
1401 && header[3] == 0x00
1402 && &header[6..14] == b"HEAPCCDR"
1403 {
1404 return Some(FileType::Crw);
1405 }
1406
1407 if header.starts_with(&[0x00, 0x4D, 0x52, 0x4D]) {
1409 return Some(FileType::Mrw);
1410 }
1411
1412 if header.starts_with(b"FOVb") {
1414 return Some(FileType::X3f);
1415 }
1416
1417 if header.len() >= 4
1419 && header[0] == b'I'
1420 && header[1] == b'I'
1421 && header[2] == 0x55
1422 && header[3] == 0x00
1423 {
1424 return Some(FileType::Rw2);
1425 }
1426
1427 if header.len() >= 12 && &header[4..8] == b"ftyp" {
1431 let brand = &header[8..12];
1432 if brand == b"heic"
1434 || brand == b"mif1"
1435 || brand == b"heim"
1436 || brand == b"heis"
1437 || brand == b"msf1"
1438 {
1439 return Some(FileType::Heif);
1440 }
1441 if brand == b"avif" || brand == b"avis" {
1443 return Some(FileType::Avif);
1444 }
1445 if brand == b"crx " {
1447 return Some(FileType::Cr3);
1448 }
1449 if brand == b"qt " {
1451 return Some(FileType::QuickTime);
1452 }
1453 if brand == b"3gp4" || brand == b"3gp5" || brand == b"3gp6" || brand == b"3g2a" {
1455 return Some(FileType::ThreeGP);
1456 }
1457 if brand == b"M4A " || brand == b"M4B " || brand == b"M4P " {
1459 return Some(FileType::M4a);
1460 }
1461 if brand == b"M4V " || brand == b"M4VH" || brand == b"M4VP" {
1462 return Some(FileType::Mp4);
1463 }
1464 if brand == b"F4V " || brand == b"F4P " {
1466 return Some(FileType::F4v);
1467 }
1468 return Some(FileType::Mp4);
1470 }
1471
1472 if header.len() >= 8 {
1474 let atom_type = &header[4..8];
1475 if atom_type == b"moov"
1476 || atom_type == b"mdat"
1477 || atom_type == b"wide"
1478 || atom_type == b"free"
1479 || atom_type == b"pnot"
1480 || atom_type == b"skip"
1481 {
1482 return Some(FileType::QuickTime);
1483 }
1484 }
1485
1486 if header.starts_with(&[0x1A, 0x45, 0xDF, 0xA3]) {
1488 return Some(FileType::Mkv);
1489 }
1491
1492 if header.starts_with(b"FLV\x01") {
1494 return Some(FileType::Flv);
1495 }
1496
1497 if header.len() >= 16 && header.starts_with(&[0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11]) {
1499 return Some(FileType::Asf);
1500 }
1502
1503 if header.len() >= 8 && header.starts_with(&[0x06, 0x0E, 0x2B, 0x34]) {
1505 return Some(FileType::Mxf);
1506 }
1507
1508 if header.len() >= 10 && header.starts_with(b"ZISRAWFILE") {
1510 return Some(FileType::Czi);
1511 }
1512
1513 if header.len() >= 40 && &header[36..40] == b"acsp" {
1515 return Some(FileType::Icc);
1516 }
1517
1518 if header.len() >= 4
1520 && header[0] == 0
1521 && header[1] == 0
1522 && header[2] == 1
1523 && (header[3] == 0xBA || header[3] == 0xBB || (header[3] & 0xF0) == 0xE0)
1524 {
1525 return Some(FileType::Mpeg);
1526 }
1527
1528 if !header.is_empty() && header[0] == 0x47 {
1530 if header.len() >= 376 && header[188] == 0x47 {
1531 return Some(FileType::M2ts);
1532 }
1533 if header.len() >= 384 && header[192] == 0x47 {
1534 return Some(FileType::M2ts);
1535 }
1536 }
1537
1538 if header.starts_with(b".RMF") {
1540 return Some(FileType::RealMedia);
1541 }
1542
1543 if header.starts_with(b"RED1") || header.starts_with(b"RED2") {
1545 return Some(FileType::R3d);
1546 }
1547
1548 if header.starts_with(b"ID3") {
1552 return Some(FileType::Mp3);
1553 }
1554 if header.len() >= 2
1558 && header[0] == 0xFF
1559 && (header[1] == 0xF0 || header[1] == 0xF1 || header[1] == 0xF8 || header[1] == 0xF9)
1560 {
1561 return Some(FileType::Aac);
1562 }
1563 if header.len() >= 2 && header[0] == 0xFF && (header[1] & 0xE0) == 0xE0 {
1565 return Some(FileType::Mp3);
1566 }
1567
1568 if header.starts_with(b"fLaC") {
1570 return Some(FileType::Flac);
1571 }
1572
1573 if header.starts_with(b"OggS") {
1575 return Some(FileType::Ogg);
1576 }
1577
1578 if header.len() >= 12
1580 && header.starts_with(b"FORM")
1581 && (&header[8..12] == b"AIFF" || &header[8..12] == b"AIFC")
1582 {
1583 return Some(FileType::Aiff);
1584 }
1585
1586 if header.starts_with(b"MAC ") {
1588 return Some(FileType::Ape);
1589 }
1590
1591 if header.len() >= 0x20 && &header[0x19..0x20] == b"ARECOYK" {
1593 return Some(FileType::KyoceraRaw);
1594 }
1595
1596 if header.starts_with(b"MP+") || header.starts_with(b"MPCK") {
1598 return Some(FileType::Mpc);
1599 }
1600
1601 if header.starts_with(b"wvpk") {
1603 return Some(FileType::WavPack);
1604 }
1605
1606 if header.starts_with(b"DSD ") {
1608 return Some(FileType::Dsf);
1609 }
1610
1611 if header.starts_with(b"OFR ") {
1613 return Some(FileType::Ofr);
1614 }
1615
1616 if header.len() >= 4
1618 && header[0] == b'.'
1619 && header[1] == b'r'
1620 && header[2] == b'a'
1621 && header[3] == 0xFD
1622 {
1623 return Some(FileType::RealAudio);
1624 }
1625
1626 if header.len() >= 4
1628 && (header[0] == 0x02 || header[0] == 0x03)
1629 && (header[1] == b'd')
1630 && (header[2] == b's')
1631 && (header[3] == b's' || header[3] == b'2')
1632 {
1633 return Some(FileType::Dss);
1634 }
1635
1636 if header.starts_with(b"%PDF-") {
1640 return Some(FileType::Pdf);
1641 }
1642
1643 if header.starts_with(b"StartFontMetrics")
1645 || header.starts_with(b"StartCompFontMetrics")
1646 || header.starts_with(b"StartMasterFontMetrics")
1647 {
1648 return Some(FileType::Afm);
1649 }
1650
1651 if header.starts_with(b"%!PS-AdobeFont-")
1654 || header.starts_with(b"%!PS-Bitstream ")
1655 || header.starts_with(b"%!FontType1-")
1656 {
1657 return Some(FileType::Pfa);
1658 }
1659
1660 if header.len() >= 21
1662 && header[0] == 0x80
1663 && header[1] == 0x01
1664 && (header[6..].starts_with(b"%!PS-AdobeFont-")
1665 || header[6..].starts_with(b"%!PS-Bitstream ")
1666 || header[6..].starts_with(b"%!FontType1-"))
1667 {
1668 return Some(FileType::Pfb);
1669 }
1670
1671 if header.starts_with(&[0xC5, 0xD0, 0xD3, 0xC6]) {
1673 return Some(FileType::Eps);
1674 }
1675 if header.starts_with(b"%!PS-Adobe-")
1676 && header[..header.len().min(32)]
1677 .windows(4)
1678 .any(|w| w == b"EPSF")
1679 {
1680 return Some(FileType::Eps);
1681 }
1682
1683 if header.starts_with(b"%!PS") || header.starts_with(b"%!Adobe") {
1685 return Some(FileType::PostScript);
1686 }
1687
1688 if header.starts_with(b"id=ImageMagick") {
1690 return Some(FileType::Miff);
1691 }
1692
1693 if header.starts_with(&[0x78, 0x9f, 0x3e, 0x22]) {
1695 return Some(FileType::Tnef);
1696 }
1697
1698 if header.starts_with(&[0xff, 0x57, 0x50, 0x43]) {
1700 return Some(FileType::Wpg);
1701 }
1702
1703 if header.len() >= 4
1705 && header[0] == 0x1f
1706 && header[1] == 0x07
1707 && header[2] == 0x00
1708 && (header[3] == 0x3f || header[3] == 0xbf)
1709 {
1710 return Some(FileType::Dv);
1711 }
1712
1713 if header.len() >= 8 && &header[4..8] == b"itch" {
1715 return Some(FileType::Itc);
1716 }
1717
1718 if header.starts_with(&[0xD0, 0xCF, 0x11, 0xE0]) {
1720 return Some(FileType::Doc); }
1722
1723 if header.starts_with(b"{\\rtf") {
1725 return Some(FileType::Rtf);
1726 }
1727
1728 if header.len() >= 8 && header.starts_with(&[0x06, 0x06, 0xED, 0xF5, 0xD8, 0x1D, 0x46, 0xE5]) {
1730 return Some(FileType::InDesign);
1731 }
1732
1733 if header.starts_with(&[0x50, 0x4B, 0x03, 0x04]) {
1737 return Some(FileType::Zip);
1738 }
1740
1741 if header.len() >= 6 && header.starts_with(b"Rar!\x1A\x07") {
1743 return Some(FileType::Rar);
1744 }
1745
1746 if header.len() >= 6 && header.starts_with(&[0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C]) {
1748 return Some(FileType::SevenZ);
1749 }
1750
1751 if header.len() >= 2 && header[0] == 0x1F && header[1] == 0x8B {
1753 return Some(FileType::Gzip);
1754 }
1755
1756 if header.len() >= 4
1758 && header[0] == 0x0A
1759 && header[1] == 0x0D
1760 && header[2] == 0x0D
1761 && header[3] == 0x0A
1762 {
1763 return Some(FileType::Pcapng);
1764 }
1765
1766 if header.len() >= 4
1768 && ((header[0] == 0xD4 && header[1] == 0xC3 && header[2] == 0xB2 && header[3] == 0xA1)
1769 || (header[0] == 0xA1 && header[1] == 0xB2 && header[2] == 0xC3 && header[3] == 0xD4))
1770 {
1771 return Some(FileType::Pcap);
1772 }
1773
1774 if header.len() >= 3
1778 && ((header[0] == b'F' || header[0] == b'C' || header[0] == b'Z')
1779 && header[1] == b'W'
1780 && header[2] == b'S')
1781 {
1782 return Some(FileType::Swf);
1783 }
1784
1785 if header.len() >= 132 && &header[128..132] == b"DICM" {
1787 return Some(FileType::Dicom);
1788 }
1789
1790 if header.len() >= 214 {
1792 let ax1 = u32::from_le_bytes([header[64], header[65], header[66], header[67]]);
1793 let ax2 = u32::from_le_bytes([header[68], header[69], header[70], header[71]]);
1794 let ax3 = u32::from_le_bytes([header[72], header[73], header[74], header[75]]);
1795 if (1..=3).contains(&ax1)
1796 && (1..=3).contains(&ax2)
1797 && (1..=3).contains(&ax3)
1798 && &header[208..211] == b"MAP"
1799 {
1800 let ms0 = header[212];
1801 let ms1 = header[213];
1802 if (ms1 == 0x41 || ms1 == 0x44) && ms0 == 0x44 || (ms0 == 0x11 && ms1 == 0x11) {
1803 return Some(FileType::Mrc);
1804 }
1805 }
1806 }
1807
1808 if header.len() >= 9 && header.starts_with(b"SIMPLE =") {
1810 return Some(FileType::Fits);
1811 }
1812
1813 if header.len() >= 4 && header[0] == 0x7E && header[1] == 0x10 && header[2] == 0x04 {
1815 return Some(FileType::Mie);
1816 }
1817
1818 if header.starts_with(b"<?xpacket") || header.starts_with(b"<x:xmpmeta") {
1820 return Some(FileType::Xmp);
1821 }
1822
1823 if header.starts_with(b"<?xml") || header.starts_with(b"<svg") {
1825 let preview = &header[..header.len().min(512)];
1826 if preview.windows(4).any(|w| w == b"<svg") {
1827 return Some(FileType::Svg);
1828 }
1829 if preview.windows(5).any(|w| w == b"<html" || w == b"<HTML") {
1830 return Some(FileType::Html); }
1832 if preview.windows(10).any(|w| w == b"<x:xmpmeta")
1833 || preview.windows(9).any(|w| w == b"<?xpacket")
1834 {
1835 return Some(FileType::Xmp);
1836 }
1837 if preview.windows(4).any(|w| w == b"<rdf" || w == b"<RDF") {
1838 return Some(FileType::Xmp);
1839 }
1840 if preview.windows(7).any(|w| w == b"<plist")
1842 || preview.windows(20).any(|w| w == b"DTD PLIST")
1843 {
1844 return Some(FileType::Plist);
1845 }
1846 if preview.windows(5).any(|w| w == b"<?aid") {
1848 return Some(FileType::Inx);
1849 }
1850 return Some(FileType::Xml);
1852 }
1853
1854 if header.starts_with(b"<!DOCTYPE html")
1856 || header.starts_with(b"<!doctype html")
1857 || header.starts_with(b"<!DOCTYPE HTML")
1858 || header.starts_with(b"<html")
1859 || header.starts_with(b"<HTML")
1860 {
1861 return Some(FileType::Html);
1862 }
1863
1864 if header.starts_with(&[0x7F, b'E', b'L', b'F']) {
1866 return Some(FileType::Exe);
1867 }
1868
1869 if header.starts_with(&[0xFE, 0xED, 0xFA, 0xCE])
1871 || header.starts_with(&[0xCE, 0xFA, 0xED, 0xFE])
1872 {
1873 return Some(FileType::Exe);
1874 }
1875
1876 if header.starts_with(&[0xFE, 0xED, 0xFA, 0xCF])
1878 || header.starts_with(&[0xCF, 0xFA, 0xED, 0xFE])
1879 {
1880 return Some(FileType::Exe);
1881 }
1882
1883 if header.starts_with(&[0xCA, 0xFE, 0xBA, 0xBE]) {
1885 return Some(FileType::Exe);
1886 }
1887
1888 if header.starts_with(b"MZ") {
1890 return Some(FileType::Exe);
1891 }
1892
1893 if (header.starts_with(&[0x00, 0x01, 0x00, 0x00])
1895 || header.starts_with(b"true")
1896 || header.starts_with(b"typ1"))
1897 && header.len() >= 12
1898 {
1899 return Some(FileType::Font);
1900 }
1901
1902 if header.starts_with(b"ttcf") {
1904 return Some(FileType::Font);
1905 }
1906
1907 if header.starts_with(b"OTTO") {
1909 return Some(FileType::Font);
1910 }
1911
1912 if header.starts_with(b"wOFF") {
1914 return Some(FileType::Font);
1915 }
1916
1917 if header.starts_with(b"wOF2") {
1919 return Some(FileType::Font);
1920 }
1921
1922 if header.len() >= 2 && header[0] == b'V' && header[1] == b'6' {
1924 return Some(FileType::Moi);
1925 }
1926
1927 if header.starts_with(b"PGF") {
1929 return Some(FileType::Pgf);
1930 }
1931
1932 if header.starts_with(b"XISF0100") {
1934 return Some(FileType::Xisf);
1935 }
1936
1937 if header.len() >= 27 && header.starts_with(b"Paint Shop Pro Image File\n\x1a") {
1939 return Some(FileType::Psp);
1940 }
1941
1942 if header.len() >= 12
1945 && header[8] == 0x00
1946 && header[9] == 0x00
1947 && header[10] == 0x00
1948 && header[11] == 0x7C
1949 {
1950 return Some(FileType::SonyPmp);
1951 }
1952
1953 None
1954}
1955
1956pub fn detect_from_extension(ext: &str) -> Option<FileType> {
1958 let ext_lower = ext.to_ascii_lowercase();
1959 let ext_lower = ext_lower.trim_start_matches('.');
1960
1961 for &ft in ALL_FILE_TYPES {
1962 for known_ext in ft.extensions() {
1963 if ext_lower == *known_ext {
1964 return Some(ft);
1965 }
1966 }
1967 }
1968
1969 None
1970}
1971
1972impl std::fmt::Display for FileType {
1973 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1974 write!(f, "{}", self.description())
1975 }
1976}
1977
1978impl std::fmt::Display for Support {
1979 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1980 match self {
1981 Support::Read => write!(f, "R"),
1982 Support::ReadWrite => write!(f, "R/W"),
1983 Support::ReadWriteCreate => write!(f, "R/W/C"),
1984 }
1985 }
1986}
1987
1988#[cfg(test)]
1989mod tests {
1990 use super::*;
1991
1992 #[test]
1993 fn test_detect_jpeg() {
1994 let header = [0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, b'J', b'F', b'I', b'F'];
1995 assert_eq!(detect_from_magic(&header), Some(FileType::Jpeg));
1996 }
1997
1998 #[test]
1999 fn test_detect_png() {
2000 let header = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
2001 assert_eq!(detect_from_magic(&header), Some(FileType::Png));
2002 }
2003
2004 #[test]
2005 fn test_detect_tiff_le() {
2006 let header = [b'I', b'I', 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00];
2007 assert_eq!(detect_from_magic(&header), Some(FileType::Tiff));
2008 }
2009
2010 #[test]
2011 fn test_detect_tiff_be() {
2012 let header = [b'M', b'M', 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08];
2013 assert_eq!(detect_from_magic(&header), Some(FileType::Tiff));
2014 }
2015
2016 #[test]
2017 fn test_detect_cr2() {
2018 let header = [b'I', b'I', 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, b'C', b'R'];
2019 assert_eq!(detect_from_magic(&header), Some(FileType::Cr2));
2020 }
2021
2022 #[test]
2023 fn test_detect_pdf() {
2024 let header = b"%PDF-1.7 some more data here";
2025 assert_eq!(detect_from_magic(header), Some(FileType::Pdf));
2026 }
2027
2028 #[test]
2029 fn test_detect_webp() {
2030 let header = b"RIFF\x00\x00\x00\x00WEBP";
2031 assert_eq!(detect_from_magic(header), Some(FileType::WebP));
2032 }
2033
2034 #[test]
2035 fn test_detect_heif() {
2036 let mut header = [0u8; 16];
2037 header[4..8].copy_from_slice(b"ftyp");
2038 header[8..12].copy_from_slice(b"heic");
2039 assert_eq!(detect_from_magic(&header), Some(FileType::Heif));
2040 }
2041
2042 #[test]
2043 fn test_detect_avif() {
2044 let mut header = [0u8; 16];
2045 header[4..8].copy_from_slice(b"ftyp");
2046 header[8..12].copy_from_slice(b"avif");
2047 assert_eq!(detect_from_magic(&header), Some(FileType::Avif));
2048 }
2049
2050 #[test]
2051 fn test_detect_cr3() {
2052 let mut header = [0u8; 16];
2053 header[4..8].copy_from_slice(b"ftyp");
2054 header[8..12].copy_from_slice(b"crx ");
2055 assert_eq!(detect_from_magic(&header), Some(FileType::Cr3));
2056 }
2057
2058 #[test]
2059 fn test_detect_flac() {
2060 assert_eq!(detect_from_magic(b"fLaC\x00\x00"), Some(FileType::Flac));
2061 }
2062
2063 #[test]
2064 fn test_detect_ogg() {
2065 assert_eq!(detect_from_magic(b"OggS\x00\x02"), Some(FileType::Ogg));
2066 }
2067
2068 #[test]
2069 fn test_detect_mp3_id3() {
2070 assert_eq!(detect_from_magic(b"ID3\x04\x00"), Some(FileType::Mp3));
2071 }
2072
2073 #[test]
2074 fn test_detect_rar() {
2075 assert_eq!(
2076 detect_from_magic(b"Rar!\x1A\x07\x01\x00"),
2077 Some(FileType::Rar)
2078 );
2079 }
2080
2081 #[test]
2082 fn test_detect_7z() {
2083 assert_eq!(
2084 detect_from_magic(&[0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C]),
2085 Some(FileType::SevenZ)
2086 );
2087 }
2088
2089 #[test]
2090 fn test_detect_gzip() {
2091 assert_eq!(
2092 detect_from_magic(&[0x1F, 0x8B, 0x08, 0x00]),
2093 Some(FileType::Gzip)
2094 );
2095 }
2096
2097 #[test]
2098 fn test_detect_raf() {
2099 assert_eq!(
2100 detect_from_magic(b"FUJIFILMCCD-RAW 0201"),
2101 Some(FileType::Raf)
2102 );
2103 }
2104
2105 #[test]
2106 fn test_detect_psd() {
2107 assert_eq!(detect_from_magic(b"8BPS\x00\x01"), Some(FileType::Psd));
2108 }
2109
2110 #[test]
2111 fn test_detect_from_extension() {
2112 assert_eq!(detect_from_extension("jpg"), Some(FileType::Jpeg));
2113 assert_eq!(detect_from_extension(".JPEG"), Some(FileType::Jpeg));
2114 assert_eq!(detect_from_extension("cr2"), Some(FileType::Cr2));
2115 assert_eq!(detect_from_extension("cr3"), Some(FileType::Cr3));
2116 assert_eq!(detect_from_extension("nef"), Some(FileType::Nef));
2117 assert_eq!(detect_from_extension("arw"), Some(FileType::Arw));
2118 assert_eq!(detect_from_extension("dng"), Some(FileType::Dng));
2119 assert_eq!(detect_from_extension("raf"), Some(FileType::Raf));
2120 assert_eq!(detect_from_extension("mp4"), Some(FileType::Mp4));
2121 assert_eq!(detect_from_extension("mov"), Some(FileType::QuickTime));
2122 assert_eq!(detect_from_extension("flac"), Some(FileType::Flac));
2123 assert_eq!(detect_from_extension("docx"), Some(FileType::Docx));
2124 assert_eq!(detect_from_extension("xlsx"), Some(FileType::Xlsx));
2125 assert_eq!(detect_from_extension("3fr"), Some(FileType::ThreeFR));
2126 assert_eq!(detect_from_extension("xyz"), None);
2127 }
2128
2129 #[test]
2130 fn test_all_types_have_extensions() {
2131 for &ft in FileType::all() {
2132 assert!(!ft.extensions().is_empty(), "{:?} has no extensions", ft);
2133 }
2134 }
2135
2136 #[test]
2137 fn test_all_types_have_mime() {
2138 for &ft in FileType::all() {
2139 assert!(!ft.mime_type().is_empty(), "{:?} has no MIME type", ft);
2140 }
2141 }
2142
2143 #[test]
2144 fn test_total_format_count() {
2145 assert!(
2146 FileType::all().len() >= 100,
2147 "Expected 100+ formats, got {}",
2148 FileType::all().len()
2149 );
2150 }
2151
2152 #[test]
2153 fn test_detect_mp4_ftyp_isom() {
2154 let mut header = [0u8; 16];
2155 header[0..4].copy_from_slice(&[0x00, 0x00, 0x00, 0x10]);
2157 header[4..8].copy_from_slice(b"ftyp");
2158 header[8..12].copy_from_slice(b"isom");
2159 assert_eq!(detect_from_magic(&header), Some(FileType::Mp4));
2160 }
2161
2162 #[test]
2163 fn test_detect_mp4_ftyp_mp42() {
2164 let mut header = [0u8; 16];
2165 header[0..4].copy_from_slice(&[0x00, 0x00, 0x00, 0x10]);
2166 header[4..8].copy_from_slice(b"ftyp");
2167 header[8..12].copy_from_slice(b"mp42");
2168 assert_eq!(detect_from_magic(&header), Some(FileType::Mp4));
2169 }
2170
2171 #[test]
2172 fn test_detect_mkv_ebml() {
2173 let header = [0x1A, 0x45, 0xDF, 0xA3, 0x93, 0x42, 0x82, 0x88];
2175 assert_eq!(detect_from_magic(&header), Some(FileType::Mkv));
2176 }
2177
2178 #[test]
2179 fn test_detect_flif() {
2180 assert_eq!(
2181 detect_from_magic(b"FLIF\x30\x00\x01\x00"),
2182 Some(FileType::Flif)
2183 );
2184 }
2185
2186 #[test]
2187 fn test_detect_bpg() {
2188 assert_eq!(
2189 detect_from_magic(&[0x42, 0x50, 0x47, 0xFB, 0x00, 0x00]),
2190 Some(FileType::Bpg)
2191 );
2192 }
2193
2194 #[test]
2195 fn test_detect_exe_mz() {
2196 assert_eq!(
2198 detect_from_magic(b"MZ\x90\x00\x03\x00\x00\x00"),
2199 Some(FileType::Exe)
2200 );
2201 }
2202
2203 #[test]
2204 fn test_detect_elf() {
2205 assert_eq!(
2206 detect_from_magic(&[0x7F, b'E', b'L', b'F', 0x02, 0x01]),
2207 Some(FileType::Exe)
2208 );
2209 }
2210
2211 #[test]
2212 fn test_detect_macho_64_le() {
2213 assert_eq!(
2215 detect_from_magic(&[0xCF, 0xFA, 0xED, 0xFE, 0x07, 0x00]),
2216 Some(FileType::Exe)
2217 );
2218 }
2219
2220 #[test]
2221 fn test_detect_macho_32_be() {
2222 assert_eq!(
2224 detect_from_magic(&[0xFE, 0xED, 0xFA, 0xCE, 0x00, 0x00]),
2225 Some(FileType::Exe)
2226 );
2227 }
2228
2229 #[test]
2230 fn test_detect_macho_fat() {
2231 assert_eq!(
2233 detect_from_magic(&[0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00]),
2234 Some(FileType::Exe)
2235 );
2236 }
2237
2238 #[test]
2239 fn test_detect_dicom() {
2240 let mut header = vec![0u8; 136];
2242 header[128..132].copy_from_slice(b"DICM");
2243 assert_eq!(detect_from_magic(&header), Some(FileType::Dicom));
2244 }
2245}