qubit-mime 0.5.2

MIME type detection utilities for Rust based on filename glob rules and content magic
Documentation
/*******************************************************************************
 *
 *    Copyright (c) 2026 Haixing Hu.
 *
 *    SPDX-License-Identifier: Apache-2.0
 *
 *    Licensed under the Apache License, Version 2.0.
 *
 ******************************************************************************/
//! Top-level media stream classifier interface.
//!

use std::fmt::Debug;
use std::io::{
    Cursor,
    Read,
};
use std::path::Path;
use std::sync::Arc;

use crate::MimeResult;

use super::MediaStreamType;

/// Classifies a media source by the audio and video streams it contains.
pub trait MediaStreamClassifier: Debug + Send + Sync {
    /// Classifies a local file.
    ///
    /// # Parameters
    /// - `file`: Local media file.
    ///
    /// # Returns
    /// Media stream classification.
    ///
    /// # Errors
    /// Returns [`MimeError::Io`](crate::MimeError::Io) when the file cannot be read, or another
    /// [`MimeError`](crate::MimeError) when the classifier backend fails.
    fn classify_file(&self, file: &Path) -> MimeResult<MediaStreamType>;

    /// Classifies media bytes from a reader.
    ///
    /// # Parameters
    /// - `reader`: Media stream to classify. The stream is consumed as needed by the classifier.
    ///
    /// # Returns
    /// Media stream classification.
    ///
    /// # Errors
    /// Returns [`MimeError::Io`](crate::MimeError::Io) when the stream cannot be read, or another
    /// [`MimeError`](crate::MimeError) when the classifier backend fails.
    fn classify_reader(&self, reader: &mut dyn Read) -> MimeResult<MediaStreamType>;

    /// Classifies an in-memory media payload.
    ///
    /// # Parameters
    /// - `content`: Media bytes to classify.
    ///
    /// # Returns
    /// Media stream classification.
    ///
    /// # Errors
    /// Returns [`MimeError::Io`](crate::MimeError::Io) when a file-backed classifier cannot stage the
    /// content.
    fn classify_content(&self, content: &[u8]) -> MimeResult<MediaStreamType> {
        let mut cursor = Cursor::new(content);
        self.classify_reader(&mut cursor)
    }
}

impl MediaStreamClassifier for Box<dyn MediaStreamClassifier> {
    /// Delegates file classification to the boxed classifier.
    fn classify_file(&self, file: &Path) -> MimeResult<MediaStreamType> {
        self.as_ref().classify_file(file)
    }

    /// Delegates stream classification to the boxed classifier.
    fn classify_reader(&self, reader: &mut dyn Read) -> MimeResult<MediaStreamType> {
        self.as_ref().classify_reader(reader)
    }
}

impl MediaStreamClassifier for Arc<dyn MediaStreamClassifier> {
    /// Delegates file classification to the shared classifier.
    fn classify_file(&self, file: &Path) -> MimeResult<MediaStreamType> {
        self.as_ref().classify_file(file)
    }

    /// Delegates stream classification to the shared classifier.
    fn classify_reader(&self, reader: &mut dyn Read) -> MimeResult<MediaStreamType> {
        self.as_ref().classify_reader(reader)
    }
}