refactor(backend): Phase 0 - Initialize multi-crate workspace
Create the foundational workspace structure for the multi-crate architecture refactor. This phase establishes placeholder crates that will be populated in subsequent phases. Crates created: - qbz-models: Shared types, events, and traits (Tier 0) - qbz-audio: Audio backend system (Tier 1) - qbz-player: Playback engine and queue (Tier 1) - qbz-qobuz: Qobuz API client (Tier 1) - qbz-core: Orchestrator (Tier 3) All crates compile successfully with placeholder implementations. The workspace uses shared dependencies via workspace.dependencies. cc
This commit is contained in:
1 parent
1c9bb8dfdb
commit
0911cf75df
12 files changed
+321
No files matched your search
@@ -71,3 +71,4 @@ qbz-nix-docs/
|
||||
|
||||
# AI agent instructions (untracked)
|
||||
.github/copilot-instructions.md
|
||||
/crates/target/
|
||||
@@ -0,0 +1,61 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
|
||||
members = [
|
||||
"qbz-models",
|
||||
"qbz-audio",
|
||||
"qbz-player",
|
||||
"qbz-qobuz",
|
||||
"qbz-core",
|
||||
]
|
||||
|
||||
# Tier 2 crates (to be added later)
|
||||
# "qbz-offlineplayback",
|
||||
# "qbz-locallibrary",
|
||||
# "qbz-cast",
|
||||
# "qbz-scrobbling",
|
||||
# "qbz-plex",
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/vicrodh/qbz"
|
||||
|
||||
[workspace.dependencies]
|
||||
# Async runtime
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
async-trait = "0.1"
|
||||
futures-util = "0.3"
|
||||
tokio-stream = { version = "0.1", features = ["sync"] }
|
||||
|
||||
# Serialization
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
# HTTP
|
||||
reqwest = { version = "0.12", features = ["json", "rustls-tls", "cookies", "stream"] }
|
||||
|
||||
# Logging
|
||||
log = "0.4"
|
||||
tracing = "0.1"
|
||||
|
||||
# Error handling
|
||||
thiserror = "2"
|
||||
anyhow = "1"
|
||||
|
||||
# Crypto (Qobuz auth)
|
||||
md-5 = "0.10"
|
||||
base64 = "0.22"
|
||||
|
||||
# Time
|
||||
chrono = "0.4"
|
||||
|
||||
# Regex
|
||||
regex = "1"
|
||||
|
||||
# Audio
|
||||
symphonia = { version = "0.5", features = ["all"] }
|
||||
|
||||
# Note: Linux-specific dependencies (alsa) go in individual crate Cargo.toml files
|
||||
# because workspace manifests cannot have [target] sections
|
||||
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "qbz-audio"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
description = "Audio backend system for QBZ - bit-perfect playback"
|
||||
|
||||
[dependencies]
|
||||
qbz-models = { path = "../qbz-models" }
|
||||
|
||||
# Async
|
||||
tokio = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
|
||||
# Logging
|
||||
log = { workspace = true }
|
||||
|
||||
# Error handling
|
||||
thiserror = { workspace = true }
|
||||
|
||||
# Audio will use vendored rodio/cpal from qbz-player
|
||||
# symphonia = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
alsa = "0.9"
|
||||
@@ -0,0 +1,25 @@
|
||||
//! QBZ Audio - Bit-perfect audio backend system
|
||||
//!
|
||||
//! This crate provides the audio backend abstraction for QBZ:
|
||||
//! - AudioBackend trait
|
||||
//! - PipeWire backend (Linux)
|
||||
//! - ALSA backend (Linux)
|
||||
//! - ALSA Direct backend (Linux, bit-perfect)
|
||||
//!
|
||||
//! # CRITICAL
|
||||
//!
|
||||
//! The audio backends in this crate are IMMUTABLE.
|
||||
//! They have been extensively debugged and tested for bit-perfect playback.
|
||||
//! DO NOT modify the logic - only imports may change.
|
||||
|
||||
// TODO: Phase 2 - Copy audio modules from qbz-nix
|
||||
// pub mod backend;
|
||||
// pub mod pipewire_backend;
|
||||
// pub mod alsa_backend;
|
||||
// pub mod alsa_direct;
|
||||
// pub mod loudness;
|
||||
// pub mod loudness_analyzer;
|
||||
// pub mod loudness_cache;
|
||||
// pub mod dynamic_amplify;
|
||||
// pub mod analyzer_tap;
|
||||
// pub mod diagnostic;
|
||||
@@ -0,0 +1,33 @@
|
||||
[package]
|
||||
name = "qbz-core"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
description = "Core orchestrator for QBZ music player"
|
||||
|
||||
[dependencies]
|
||||
qbz-models = { path = "../qbz-models" }
|
||||
qbz-audio = { path = "../qbz-audio" }
|
||||
qbz-player = { path = "../qbz-player" }
|
||||
qbz-qobuz = { path = "../qbz-qobuz" }
|
||||
|
||||
# Async
|
||||
tokio = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
|
||||
# Logging
|
||||
log = { workspace = true }
|
||||
|
||||
# Error handling
|
||||
thiserror = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
# Tier 2 features (to be added later)
|
||||
# offline = ["qbz-offlineplayback"]
|
||||
# local-library = ["qbz-locallibrary"]
|
||||
# cast = ["qbz-cast"]
|
||||
# scrobbling = ["qbz-scrobbling"]
|
||||
# plex = ["qbz-plex"]
|
||||
# full = ["offline", "local-library", "cast", "scrobbling", "plex"]
|
||||
@@ -0,0 +1,34 @@
|
||||
//! QBZ Core - Orchestrator for QBZ music player
|
||||
//!
|
||||
//! This crate provides the main entry point for QBZ:
|
||||
//! - QbzCore<A: FrontendAdapter>: Main orchestrator struct
|
||||
//! - Connects all subsystems (audio, player, queue, API)
|
||||
//! - Provides unified public API for frontends
|
||||
//!
|
||||
//! # Usage
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
//! use qbz_core::{QbzCore, FrontendAdapter, CoreEvent};
|
||||
//!
|
||||
//! struct MyAdapter;
|
||||
//!
|
||||
//! impl FrontendAdapter for MyAdapter {
|
||||
//! async fn on_event(&self, event: CoreEvent) {
|
||||
//! // Handle event, update UI
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! let core = QbzCore::new(MyAdapter);
|
||||
//! core.init().await?;
|
||||
//! core.login("email", "password").await?;
|
||||
//! core.play_track(track_id).await?;
|
||||
//! ```
|
||||
|
||||
// TODO: Phase 5 - Implement core orchestrator
|
||||
// pub mod core;
|
||||
// pub mod error;
|
||||
|
||||
// Re-exports
|
||||
// pub use qbz_models::*;
|
||||
// pub use core::QbzCore;
|
||||
// pub use error::CoreError;
|
||||
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "qbz-models"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
description = "Shared types, events, and traits for QBZ music player"
|
||||
|
||||
[dependencies]
|
||||
# Serialization
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
# Async
|
||||
async-trait = { workspace = true }
|
||||
|
||||
# Error handling
|
||||
thiserror = { workspace = true }
|
||||
|
||||
# Time
|
||||
chrono = { workspace = true }
|
||||
@@ -0,0 +1,15 @@
|
||||
//! QBZ Models - Shared types, events, and traits
|
||||
//!
|
||||
//! This crate provides the foundation for all QBZ crates:
|
||||
//! - Type definitions (Track, Album, Artist, etc.)
|
||||
//! - Event definitions (CoreEvent enum)
|
||||
//! - Trait definitions (FrontendAdapter)
|
||||
//! - Configuration types
|
||||
|
||||
// TODO: Phase 1 - Implement these modules
|
||||
// pub mod types;
|
||||
// pub mod playback;
|
||||
// pub mod events;
|
||||
// pub mod traits;
|
||||
// pub mod config;
|
||||
// pub mod error;
|
||||
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
name = "qbz-player"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
description = "Playback engine and queue management for QBZ"
|
||||
|
||||
[dependencies]
|
||||
qbz-models = { path = "../qbz-models" }
|
||||
qbz-audio = { path = "../qbz-audio" }
|
||||
|
||||
# Async
|
||||
tokio = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
futures-util = { workspace = true }
|
||||
tokio-stream = { workspace = true }
|
||||
|
||||
# Logging
|
||||
log = { workspace = true }
|
||||
|
||||
# Error handling
|
||||
thiserror = { workspace = true }
|
||||
|
||||
# Audio decoding
|
||||
symphonia = { workspace = true }
|
||||
|
||||
# Vendored audio libraries (will be copied in Phase 3)
|
||||
# rodio = { path = "./vendor/rodio", features = ["symphonia-all"] }
|
||||
# cpal = { path = "./vendor/cpal" }
|
||||
@@ -0,0 +1,21 @@
|
||||
//! QBZ Player - Playback engine and queue management
|
||||
//!
|
||||
//! This crate provides:
|
||||
//! - Player: Main playback control
|
||||
//! - QueueManager: Track queue management
|
||||
//! - StreamingSource: HTTP audio streaming
|
||||
//! - PlaybackCache: In-memory prefetch cache
|
||||
//!
|
||||
//! The vendor/ directory contains modified versions of:
|
||||
//! - rodio: High-level audio playback
|
||||
//! - cpal: Cross-platform audio I/O
|
||||
|
||||
// TODO: Phase 3 - Copy player modules from qbz-nix
|
||||
// pub mod player;
|
||||
// pub mod queue;
|
||||
// pub mod streaming_source;
|
||||
// pub mod playback_engine;
|
||||
// pub mod playback_cache;
|
||||
|
||||
// pub use player::Player;
|
||||
// pub use queue::QueueManager;
|
||||
@@ -0,0 +1,35 @@
|
||||
[package]
|
||||
name = "qbz-qobuz"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
description = "Qobuz API client for QBZ"
|
||||
|
||||
[dependencies]
|
||||
qbz-models = { path = "../qbz-models" }
|
||||
|
||||
# Async
|
||||
tokio = { workspace = true }
|
||||
|
||||
# HTTP
|
||||
reqwest = { workspace = true }
|
||||
|
||||
# Serialization
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
# Crypto (for Qobuz auth)
|
||||
md-5 = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
|
||||
# Time
|
||||
chrono = { workspace = true }
|
||||
|
||||
# Regex
|
||||
regex = { workspace = true }
|
||||
|
||||
# Logging
|
||||
log = { workspace = true }
|
||||
|
||||
# Error handling
|
||||
thiserror = { workspace = true }
|
||||
@@ -0,0 +1,22 @@
|
||||
//! QBZ Qobuz - Qobuz API client
|
||||
//!
|
||||
//! This crate provides the Qobuz API client:
|
||||
//! - QobuzClient: Main API interface
|
||||
//! - Authentication and token management
|
||||
//! - Search, catalog browsing, streaming URLs
|
||||
//!
|
||||
//! The client handles:
|
||||
//! - Bundle token extraction
|
||||
//! - Request signing
|
||||
//! - Session management
|
||||
|
||||
// TODO: Phase 4 - Copy API modules from qbz-nix
|
||||
// pub mod client;
|
||||
// pub mod auth;
|
||||
// pub mod endpoints;
|
||||
// pub mod bundle;
|
||||
// pub mod performers;
|
||||
// pub mod error;
|
||||
|
||||
// pub use client::QobuzClient;
|
||||
// pub use error::ApiError;
|
||||
Reference in new issue
Block a user