Skip to main content

qubit_mime/classifier/
file_based_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//! File-backed media stream classifier helpers.
9
10use std::fmt::Debug;
11use std::io::Read;
12use std::path::Path;
13
14use crate::DEFAULT_MEDIA_STREAM_MAX_STAGING_SIZE;
15use crate::{
16    MediaStreamClassifierBackend,
17    MediaStreamType,
18    MimeResult,
19};
20
21use super::media_stream_classifier_helpers::with_temp_reader;
22
23/// Core implementation contract for classifiers that only operate on local
24/// files.
25pub trait FileBasedMediaStreamClassifier: Debug + Send + Sync {
26    /// Gets the maximum bytes staged from reader/content input.
27    ///
28    /// # Returns
29    /// Maximum accepted stream size before staging is rejected.
30    fn max_staging_size(&self) -> u64 {
31        DEFAULT_MEDIA_STREAM_MAX_STAGING_SIZE
32    }
33
34    /// Classifies one validated local file.
35    ///
36    /// # Parameters
37    /// - `file`: Readable local media file.
38    ///
39    /// # Returns
40    /// Media stream classification.
41    ///
42    /// # Errors
43    /// Returns [`MimeError::Io`](crate::MimeError::Io) or another
44    /// [`MimeError`](crate::MimeError) when backend classification fails.
45    fn classify_by_local_file(
46        &self,
47        file: &Path,
48    ) -> MimeResult<MediaStreamType>;
49}
50
51impl<T> MediaStreamClassifierBackend for T
52where
53    T: FileBasedMediaStreamClassifier,
54{
55    /// Delegates local-file classification to the file-based hook.
56    fn classify_by_local_file(
57        &self,
58        file: &Path,
59    ) -> MimeResult<MediaStreamType> {
60        FileBasedMediaStreamClassifier::classify_by_local_file(self, file)
61    }
62
63    /// Stages stream content to a temporary local file before classification.
64    fn classify_by_content(
65        &self,
66        reader: &mut dyn Read,
67    ) -> MimeResult<MediaStreamType> {
68        with_temp_reader(reader, self.max_staging_size(), |path| {
69            FileBasedMediaStreamClassifier::classify_by_local_file(self, path)
70        })
71    }
72}