Skip to main content

qubit_mime/classifier/
media_stream_classifier.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Top-level media stream classifier interface.
9
10use std::fmt::Debug;
11use std::io::{
12    Cursor,
13    Read,
14};
15use std::path::Path;
16use std::sync::Arc;
17
18use crate::MimeResult;
19
20use super::MediaStreamType;
21
22/// Classifies a media source by the audio and video streams it contains.
23pub trait MediaStreamClassifier: Debug + Send + Sync {
24    /// Classifies a local file.
25    ///
26    /// # Parameters
27    /// - `file`: Local media file.
28    ///
29    /// # Returns
30    /// Media stream classification.
31    ///
32    /// # Errors
33    /// Returns [`MimeError::Io`](crate::MimeError::Io) when the file cannot be
34    /// read, or another [`MimeError`](crate::MimeError) when the classifier
35    /// backend fails.
36    fn classify_file(&self, file: &Path) -> MimeResult<MediaStreamType>;
37
38    /// Classifies media bytes from a reader.
39    ///
40    /// # Parameters
41    /// - `reader`: Media stream to classify. The stream is consumed as needed
42    ///   by the classifier.
43    ///
44    /// # Returns
45    /// Media stream classification.
46    ///
47    /// # Errors
48    /// Returns [`MimeError::Io`](crate::MimeError::Io) when the stream cannot
49    /// be read, or another [`MimeError`](crate::MimeError) when the
50    /// classifier backend fails.
51    fn classify_reader(
52        &self,
53        reader: &mut dyn Read,
54    ) -> MimeResult<MediaStreamType>;
55
56    /// Classifies an in-memory media payload.
57    ///
58    /// # Parameters
59    /// - `content`: Media bytes to classify.
60    ///
61    /// # Returns
62    /// Media stream classification.
63    ///
64    /// # Errors
65    /// Returns [`MimeError::Io`](crate::MimeError::Io) when a file-backed
66    /// classifier cannot stage the content.
67    fn classify_content(&self, content: &[u8]) -> MimeResult<MediaStreamType> {
68        let mut cursor = Cursor::new(content);
69        self.classify_reader(&mut cursor)
70    }
71}
72
73impl MediaStreamClassifier for Box<dyn MediaStreamClassifier> {
74    /// Delegates file classification to the boxed classifier.
75    fn classify_file(&self, file: &Path) -> MimeResult<MediaStreamType> {
76        self.as_ref().classify_file(file)
77    }
78
79    /// Delegates stream classification to the boxed classifier.
80    fn classify_reader(
81        &self,
82        reader: &mut dyn Read,
83    ) -> MimeResult<MediaStreamType> {
84        self.as_ref().classify_reader(reader)
85    }
86}
87
88impl MediaStreamClassifier for Arc<dyn MediaStreamClassifier> {
89    /// Delegates file classification to the shared classifier.
90    fn classify_file(&self, file: &Path) -> MimeResult<MediaStreamType> {
91        self.as_ref().classify_file(file)
92    }
93
94    /// Delegates stream classification to the shared classifier.
95    fn classify_reader(
96        &self,
97        reader: &mut dyn Read,
98    ) -> MimeResult<MediaStreamType> {
99        self.as_ref().classify_reader(reader)
100    }
101}