qubit_mime/lib.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! # Qubit MIME
11//!
12//! MIME type detection based on filename glob rules, content magic rules, and
13//! optional native command backends.
14//!
15//! The crate ships with two detector providers:
16//!
17//! - `repository`: an embedded detector that uses the bundled MIME repository.
18//! - `file`: a detector that delegates content detection to the system
19//! `file --mime-type --brief` command and uses the repository for filename
20//! guesses.
21//!
22//! Detectors are created through [`MimeDetectorRegistry`]. The configured
23//! default detector is tried first, followed by the configured fallback chain.
24//! The special selector `auto` chooses the highest-priority available provider
25//! from the registry.
26//!
27//! # Examples
28//!
29//! Create a detector from the default configuration:
30//!
31//! ```rust
32//! use qubit_mime::{
33//! MimeConfig,
34//! MimeDetector,
35//! MimeDetectorRegistry,
36//! MimeResult,
37//! };
38//!
39//! # fn main() -> MimeResult<()> {
40//! let detector =
41//! MimeDetectorRegistry::default_registry()?.create_default_box(&MimeConfig::default())?;
42//! assert_eq!(
43//! Some("application/pdf".to_owned()),
44//! detector.detect_by_filename("document.pdf"),
45//! );
46//! # Ok(())
47//! # }
48//! ```
49//!
50//! Configure a preferred detector and an explicit fallback. This is useful when
51//! `file` should be used on systems where it is available, while still allowing
52//! deterministic repository detection on minimal CI images:
53//!
54//! ```rust
55//! use qubit_config::Config;
56//! use qubit_mime::{
57//! CONFIG_MIME_DETECTOR_DEFAULT,
58//! CONFIG_MIME_DETECTOR_FALLBACKS,
59//! MimeConfig,
60//! MimeDetector,
61//! MimeDetectorRegistry,
62//! MimeResult,
63//! };
64//!
65//! # fn main() -> MimeResult<()> {
66//! let mut source = Config::new();
67//! source.set(CONFIG_MIME_DETECTOR_DEFAULT, "file")?;
68//! source.set(CONFIG_MIME_DETECTOR_FALLBACKS, "repository")?;
69//!
70//! let config = MimeConfig::from_config(&source)?;
71//! let detector = MimeDetectorRegistry::default_registry()?.create_default_box(&config)?;
72//! assert_eq!(
73//! Some("image/png".to_owned()),
74//! detector.detect_by_filename("image.png"),
75//! );
76//! # Ok(())
77//! # }
78//! ```
79
80pub mod classifier;
81pub mod detector;
82pub mod repository;
83
84pub use qubit_spi::{
85 ProviderAvailability,
86 ProviderCreateError,
87 ProviderDescriptor,
88 ProviderFailure,
89 ProviderName,
90 ProviderRegistryError,
91 ProviderSelection,
92 ServiceProvider,
93 ServiceSpec,
94};
95
96mod common_mime_types;
97mod constants;
98mod mime_config;
99mod mime_error;
100mod mime_result;
101
102pub use classifier::{
103 FfprobeCommandMediaStreamClassifier,
104 FfprobeCommandMediaStreamClassifierProvider,
105 FileBasedMediaStreamClassifier,
106 MediaStreamClassifier,
107 MediaStreamClassifierAvailability,
108 MediaStreamClassifierBackend,
109 MediaStreamClassifierProvider,
110 MediaStreamClassifierRegistry,
111 MediaStreamClassifierSpec,
112 MediaStreamType,
113};
114pub use common_mime_types::*;
115pub use constants::*;
116pub use detector::{
117 DetectionSource,
118 FileBasedMimeDetector,
119 FileCommandMimeDetector,
120 FileCommandMimeDetectorProvider,
121 MimeDetectionPolicy,
122 MimeDetector,
123 MimeDetectorAvailability,
124 MimeDetectorBackend,
125 MimeDetectorCore,
126 MimeDetectorProvider,
127 MimeDetectorRegistry,
128 MimeDetectorSpec,
129 RepositoryMimeDetector,
130 RepositoryMimeDetectorProvider,
131 StreamBasedMimeDetector,
132};
133pub use mime_config::MimeConfig;
134pub use mime_error::MimeError;
135pub use mime_result::MimeResult;
136pub use repository::{
137 MagicValueType,
138 MimeGlob,
139 MimeMagic,
140 MimeMagicMatcher,
141 MimeRepository,
142 MimeType,
143 MimeTypeBuilder,
144};