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