Elabore une crate pmosource

This commit is contained in:
2025-10-16 22:00:35 +02:00
parent 68b0c89130
commit e0fbb11475
16 changed files with 561 additions and 1 deletions

112
pmosource/src/lib.rs Normal file
View File

@@ -0,0 +1,112 @@
//! # PMOSource
//!
//! Common traits and types for PMOMusic sources.
//!
//! This crate provides the foundational abstractions for different music sources
//! in the PMOMusic ecosystem, such as Radio Paradise, Qobuz, etc.
use std::fmt::Debug;
/// Standard size for default images (300x300 pixels)
pub const DEFAULT_IMAGE_SIZE: u32 = 300;
/// Error types for music source operations
#[derive(Debug, thiserror::Error)]
pub enum MusicSourceError {
#[error("Failed to load default image: {0}")]
ImageLoadError(String),
#[error("Invalid image format: {0}")]
InvalidImageFormat(String),
#[error("Source not available: {0}")]
SourceUnavailable(String),
}
/// Result type for music source operations
pub type Result<T> = std::result::Result<T, MusicSourceError>;
/// Main trait for music sources
///
/// This trait defines the common interface that all music sources must implement.
/// It provides methods for:
/// - Getting the source name and identification
/// - Retrieving default images/logos
/// - Other common operations (to be extended)
pub trait MusicSource: Debug + Send + Sync {
/// Returns the human-readable name of the music source
///
/// # Examples
///
/// ```ignore
/// assert_eq!(source.name(), "Radio Paradise");
/// ```
fn name(&self) -> &str;
/// Returns a unique identifier for the music source
///
/// This is typically a lowercase, hyphenated version of the name
/// suitable for use in URLs, file names, etc.
///
/// # Examples
///
/// ```ignore
/// assert_eq!(source.id(), "radio-paradise");
/// ```
fn id(&self) -> &str;
/// Returns the default image/logo for this source as WebP bytes
///
/// The image should be square (300x300 pixels) and in WebP format.
/// This is embedded in the binary for offline availability.
///
/// # Returns
///
/// A byte slice containing the WebP-encoded image data
///
/// # Examples
///
/// ```ignore
/// let image_data = source.default_image();
/// assert!(image_data.len() > 0);
/// ```
fn default_image(&self) -> &[u8];
/// Returns the MIME type of the default image
///
/// By default, this returns "image/webp" since all default images
/// should be in WebP format.
fn default_image_mime_type(&self) -> &str {
"image/webp"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug)]
struct TestSource;
impl MusicSource for TestSource {
fn name(&self) -> &str {
"Test Source"
}
fn id(&self) -> &str {
"test-source"
}
fn default_image(&self) -> &[u8] {
&[]
}
}
#[test]
fn test_music_source_trait() {
let source = TestSource;
assert_eq!(source.name(), "Test Source");
assert_eq!(source.id(), "test-source");
assert_eq!(source.default_image_mime_type(), "image/webp");
}
}