From 5f78dcaaf711bddcf35a5c6effaee259007251fb Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sat, 3 May 2025 22:18:26 +0200 Subject: [PATCH 1/7] fix: add unreachable variant to DecoderImpl for no enabled decoders Co-authored-by: @renski-dev --- src/decoder/mod.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index ef2486e3..ac0b4fc7 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -119,8 +119,14 @@ enum DecoderImpl { Mp3(mp3::Mp3Decoder), #[cfg(feature = "symphonia")] Symphonia(symphonia::SymphoniaDecoder, PhantomData), + // This variant is here just to satisfy the compiler when there are no decoders enabled. + // It is unreachable and should never be constructed. + #[allow(dead_code)] + None(Unreachable, PhantomData), } +enum Unreachable {} + impl DecoderImpl { #[inline] fn next(&mut self) -> Option { @@ -135,6 +141,7 @@ impl DecoderImpl { DecoderImpl::Mp3(source) => source.next(), #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source, PhantomData) => source.next(), + DecoderImpl::None(_, _) => unreachable!(), } } @@ -151,6 +158,7 @@ impl DecoderImpl { DecoderImpl::Mp3(source) => source.size_hint(), #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source, PhantomData) => source.size_hint(), + DecoderImpl::None(_, _) => unreachable!(), } } @@ -167,6 +175,7 @@ impl DecoderImpl { DecoderImpl::Mp3(source) => source.current_span_len(), #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source, PhantomData) => source.current_span_len(), + DecoderImpl::None(_, _) => unreachable!(), } } @@ -183,6 +192,7 @@ impl DecoderImpl { DecoderImpl::Mp3(source) => source.channels(), #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source, PhantomData) => source.channels(), + DecoderImpl::None(_, _) => unreachable!(), } } @@ -199,6 +209,7 @@ impl DecoderImpl { DecoderImpl::Mp3(source) => source.sample_rate(), #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source, PhantomData) => source.sample_rate(), + DecoderImpl::None(_, _) => unreachable!(), } } @@ -221,6 +232,7 @@ impl DecoderImpl { DecoderImpl::Mp3(source) => source.total_duration(), #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source, PhantomData) => source.total_duration(), + DecoderImpl::None(_, _) => unreachable!(), } } @@ -237,6 +249,7 @@ impl DecoderImpl { DecoderImpl::Mp3(source) => source.try_seek(pos), #[cfg(feature = "symphonia")] DecoderImpl::Symphonia(source, PhantomData) => source.try_seek(pos), + DecoderImpl::None(_, _) => unreachable!(), } } } From 76bfa3617603b2af21f8ee64b58f3669dc4ad55b Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sat, 3 May 2025 22:27:48 +0200 Subject: [PATCH 2/7] refactor: clippy lints --- tests/seek.rs | 5 +---- tests/total_duration.rs | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/seek.rs b/tests/seek.rs index c4a402e0..35d6ddd6 100644 --- a/tests/seek.rs +++ b/tests/seek.rs @@ -175,10 +175,7 @@ fn seek_does_not_break_channel_order( } } -fn second_channel_beep_range(source: &mut R) -> std::ops::Range -where - R: Iterator, -{ +fn second_channel_beep_range(source: &mut R) -> std::ops::Range { let channels = source.channels() as usize; let samples: Vec = source.by_ref().collect(); diff --git a/tests/total_duration.rs b/tests/total_duration.rs index fecaaa3f..7298d661 100644 --- a/tests/total_duration.rs +++ b/tests/total_duration.rs @@ -72,9 +72,7 @@ fn decoder_returns_total_duration( let decoder = get_music(format); let res = decoder .total_duration() - .expect(&format!( - "did not return a total duration, decoder: {decoder_name}" - )) + .unwrap_or_else(|| panic!("did not return a total duration, decoder: {decoder_name}")) .as_secs_f64(); let correct_duration = correct_duration.as_secs_f64(); let abs_diff = (res - correct_duration).abs(); From 0498f72a736d70f48b451913ac445c4dc4f997a0 Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Mon, 2 Jun 2025 21:36:33 +0200 Subject: [PATCH 3/7] Fix testing and compilation with no default features Make the minimal build on the CI absolutely minimal and add conditional compilation guards to examples and tests. All examples now show helpful messages when playback feature is disabled, and tests properly handle cases where no decoders are available. --- .github/workflows/ci.yml | 11 +++-- examples/automatic_gain_control.rs | 10 +++++ examples/basic.rs | 9 +++++ examples/callback_on_end.rs | 9 +++++ examples/custom_config.rs | 11 +++++ examples/error_callback.rs | 10 +++++ examples/low_pass.rs | 9 +++++ examples/mix_multiple_sources.rs | 9 +++++ examples/music_flac.rs | 9 +++++ examples/music_m4a.rs | 9 +++++ examples/music_mp3.rs | 9 +++++ examples/music_ogg.rs | 9 +++++ examples/music_wav.rs | 9 +++++ examples/noise_generator.rs | 7 ++-- examples/reverb.rs | 9 +++++ examples/seek_mp3.rs | 9 +++++ examples/signal_generator.rs | 8 ++++ examples/spatial.rs | 9 +++++ examples/stereo.rs | 8 ++++ src/lib.rs | 22 +++++++--- src/source/speed.rs | 6 ++- tests/seek.rs | 64 ++++++++++++++++++++++++++++++ tests/total_duration.rs | 24 +++++++++++ 23 files changed, 273 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f661ffd..f1ed0faf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: CI on: pull_request: push: - branches: [ main, master ] + branches: [main, master] env: RUSTFLAGS: "-C debuginfo=0 -D warnings" @@ -18,8 +18,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ macos-latest, windows-latest, ubuntu-latest ] - toolchain: [ stable, beta, nightly ] + os: [macos-latest, windows-latest, ubuntu-latest] + toolchain: [stable, beta, nightly] include: - os: macos-latest MACOS: true @@ -49,6 +49,5 @@ jobs: # `cargo test` does not check benchmarks and `cargo test --all-targets` excludes # documentation tests. Therefore, we need an additional docs test command here. - run: cargo test --doc - # Check minimal build. `tests/seek.rs` fails if there are no decoders at all, - # adding one to make the tests check pass. - - run: cargo check --tests --lib --no-default-features --features mp3 + # Check minimal build. + - run: cargo check --tests --lib --no-default-features diff --git a/examples/automatic_gain_control.rs b/examples/automatic_gain_control.rs index 884d046a..bf027556 100644 --- a/examples/automatic_gain_control.rs +++ b/examples/automatic_gain_control.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use rodio::source::Source; use rodio::Decoder; use std::error::Error; @@ -7,6 +9,7 @@ use std::sync::Arc; use std::thread; use std::time::Duration; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -43,5 +46,12 @@ fn main() -> Result<(), Box> { // Keep the program running until the playback is complete. sink.sleep_until_end(); + Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/basic.rs b/examples/basic.rs index 5628bd3b..0a2989fd 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use rodio::source::SineWave; use rodio::Source; use std::error::Error; @@ -5,6 +7,7 @@ use std::io::BufReader; use std::thread; use std::time::Duration; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let mixer = stream_handle.mixer(); @@ -50,3 +53,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/callback_on_end.rs b/examples/callback_on_end.rs index f367f7f4..ad9184ae 100644 --- a/examples/callback_on_end.rs +++ b/examples/callback_on_end.rs @@ -1,7 +1,10 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -36,3 +39,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/custom_config.rs b/examples/custom_config.rs index 4e1ff76a..e931180a 100644 --- a/examples/custom_config.rs +++ b/examples/custom_config.rs @@ -1,4 +1,8 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + +#[cfg(feature = "playback")] use cpal::traits::HostTrait; +#[cfg(feature = "playback")] use cpal::{BufferSize, SampleFormat}; use rodio::source::SineWave; use rodio::Source; @@ -6,6 +10,7 @@ use std::error::Error; use std::thread; use std::time::Duration; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { // You can use any other output device that can be queried from CPAL. let default_device = cpal::default_host() @@ -33,3 +38,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/error_callback.rs b/examples/error_callback.rs index bb55ebdf..7161532b 100644 --- a/examples/error_callback.rs +++ b/examples/error_callback.rs @@ -1,9 +1,13 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + +#[cfg(feature = "playback")] use cpal::traits::HostTrait; use rodio::source::SineWave; use rodio::Source; use std::error::Error; use std::time::Duration; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { // You can use any other output device that can be queried from CPAL. let default_device = cpal::default_host() @@ -39,3 +43,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/low_pass.rs b/examples/low_pass.rs index ec343888..853ec785 100644 --- a/examples/low_pass.rs +++ b/examples/low_pass.rs @@ -1,8 +1,11 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; use std::io::BufReader; use rodio::Source; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -16,3 +19,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/mix_multiple_sources.rs b/examples/mix_multiple_sources.rs index 75109c8b..0681d0a3 100644 --- a/examples/mix_multiple_sources.rs +++ b/examples/mix_multiple_sources.rs @@ -1,8 +1,11 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use rodio::mixer; use rodio::source::{SineWave, Source}; use std::error::Error; use std::time::Duration; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { // Construct a dynamic controller and mixer, stream_handle, and sink. let (controller, mixer) = mixer::mixer(2, 44_100); @@ -39,3 +42,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/music_flac.rs b/examples/music_flac.rs index f93028be..4a746b2a 100644 --- a/examples/music_flac.rs +++ b/examples/music_flac.rs @@ -1,5 +1,8 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -11,3 +14,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/music_m4a.rs b/examples/music_m4a.rs index ca7c4391..8dd8afd5 100644 --- a/examples/music_m4a.rs +++ b/examples/music_m4a.rs @@ -1,5 +1,8 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(&stream_handle.mixer()); @@ -11,3 +14,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/music_mp3.rs b/examples/music_mp3.rs index bacc7309..a9a254a3 100644 --- a/examples/music_mp3.rs +++ b/examples/music_mp3.rs @@ -1,5 +1,8 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -11,3 +14,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/music_ogg.rs b/examples/music_ogg.rs index f44dfec0..43e9819e 100644 --- a/examples/music_ogg.rs +++ b/examples/music_ogg.rs @@ -1,5 +1,8 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -11,3 +14,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/music_wav.rs b/examples/music_wav.rs index ea50de38..bd80a998 100644 --- a/examples/music_wav.rs +++ b/examples/music_wav.rs @@ -1,5 +1,8 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -11,3 +14,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/noise_generator.rs b/examples/noise_generator.rs index f22d3712..0d73c1e6 100644 --- a/examples/noise_generator.rs +++ b/examples/noise_generator.rs @@ -1,8 +1,9 @@ //! Noise generator example. Use the "noise" feature to enable the noise generator sources. +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] use std::error::Error; -#[cfg(feature = "noise")] +#[cfg(all(feature = "noise", feature = "playback"))] fn main() -> Result<(), Box> { use rodio::source::{pink, white, Source}; use std::thread; @@ -30,8 +31,8 @@ fn main() -> Result<(), Box> { Ok(()) } -#[cfg(not(feature = "noise"))] +#[cfg(not(all(feature = "noise", feature = "playback")))] fn main() { - println!("rodio has not been compiled with noise sources, use `--features noise` to enable this feature."); + println!("rodio has not been compiled with noise sources, use `--features noise,playback` to enable this feature."); println!("Exiting..."); } diff --git a/examples/reverb.rs b/examples/reverb.rs index b8c04b52..a9cd180e 100644 --- a/examples/reverb.rs +++ b/examples/reverb.rs @@ -1,7 +1,10 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use rodio::Source; use std::error::Error; use std::time::Duration; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -15,3 +18,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/seek_mp3.rs b/examples/seek_mp3.rs index c27f5346..c977d009 100644 --- a/examples/seek_mp3.rs +++ b/examples/seek_mp3.rs @@ -1,6 +1,9 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; use std::time::Duration; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -22,3 +25,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/signal_generator.rs b/examples/signal_generator.rs index 1ae4048e..be7c5a07 100644 --- a/examples/signal_generator.rs +++ b/examples/signal_generator.rs @@ -1,7 +1,9 @@ //! Test signal generator example. +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] use std::error::Error; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { use rodio::source::{chirp, Function, SignalGenerator, Source}; use std::thread; @@ -69,3 +71,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/spatial.rs b/examples/spatial.rs index f1b97e44..6946e6f6 100644 --- a/examples/spatial.rs +++ b/examples/spatial.rs @@ -1,9 +1,12 @@ +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] + use std::error::Error; use std::thread; use std::time::Duration; use rodio::Source; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let iter_duration = Duration::from_secs(5); let iter_distance = 5.; @@ -58,3 +61,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/examples/stereo.rs b/examples/stereo.rs index c86eef73..8a1315ed 100644 --- a/examples/stereo.rs +++ b/examples/stereo.rs @@ -1,8 +1,10 @@ //! Plays a tone alternating between right and left ears, with right being first. +#![cfg_attr(not(feature = "playback"), allow(unused_imports))] use rodio::Source; use std::error::Error; +#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -14,3 +16,9 @@ fn main() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "playback"))] +fn main() { + println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); + println!("Exiting..."); +} diff --git a/src/lib.rs b/src/lib.rs index 07457d91..18dfd2a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,8 @@ //! //! Here is a complete example of how you would play an audio file: //! -//! ```no_run +#![cfg_attr(not(feature = "playback"), doc = "```ignore")] +#![cfg_attr(feature = "playback", doc = "```no_run")] //! use std::fs::File; //! use rodio::{Decoder, OutputStream, source::Source}; //! @@ -34,7 +35,8 @@ //! ``` //! //! [`rodio::play()`](crate::play) helps to simplify the above -//! ```no_run +#![cfg_attr(not(feature = "playback"), doc = "```ignore")] +#![cfg_attr(feature = "playback", doc = "```no_run")] //! use std::fs::File; //! use std::io::BufReader; //! use rodio::{Decoder, OutputStream, source::Source}; @@ -63,7 +65,8 @@ //! To play a soung Create a [`Sink`] connect it to the output stream, //! and [`.append()`](Sink::append) your sound to it. //! -//! ```no_run +#![cfg_attr(not(feature = "playback"), doc = "```ignore")] +#![cfg_attr(feature = "playback", doc = "```no_run")] //! use std::time::Duration; //! use rodio::{OutputStream, Sink}; //! use rodio::source::{SineWave, Source}; @@ -96,7 +99,8 @@ //! //! Example: //! -//! ``` +#![cfg_attr(not(feature = "playback"), doc = "```ignore")] +#![cfg_attr(feature = "playback", doc = "```")] //! use rodio::Source; //! use std::time::Duration; //! @@ -147,7 +151,15 @@ //! on the number of sinks that can be created (except for the fact that creating too many will slow //! down your program). -#![cfg_attr(test, deny(missing_docs))] +#![cfg_attr( + any(test, not(feature = "playback")), + deny(missing_docs), + allow(dead_code), + allow(unused_imports), + allow(unused_variables), + allow(unreachable_code) +)] + #[cfg(feature = "playback")] pub use cpal::{ self, traits::DeviceTrait, Device, Devices, DevicesError, InputDevices, OutputDevices, diff --git a/src/source/speed.rs b/src/source/speed.rs index 5f47e8da..9454ed98 100644 --- a/src/source/speed.rs +++ b/src/source/speed.rs @@ -11,7 +11,8 @@ //! To speed up a source from sink all you need to do is call the `set_speed(factor: f32)` function //! For example, here is how you speed up your sound by using sink or playing raw: //! -//! ```no_run +#![cfg_attr(not(feature = "playback"), doc = "```ignore")] +#![cfg_attr(feature = "playback", doc = "```no_run")] //!# use std::fs::File; //!# use rodio::{Decoder, Sink, OutputStream, source::{Source, SineWave}}; //! @@ -28,7 +29,8 @@ //! std::thread::sleep(std::time::Duration::from_secs(5)); //! ``` //! Here is how you would do it using the sink: -//!```no_run +#![cfg_attr(not(feature = "playback"), doc = "```ignore")] +#![cfg_attr(feature = "playback", doc = "```no_run")] //! use rodio::source::{Source, SineWave}; //! let source = SineWave::new(440.0) //! .take_duration(std::time::Duration::from_secs_f32(20.25)) diff --git a/tests/seek.rs b/tests/seek.rs index 35d6ddd6..64f0963a 100644 --- a/tests/seek.rs +++ b/tests/seek.rs @@ -1,3 +1,6 @@ +#![allow(dead_code)] +#![allow(unused_imports)] + use rodio::{ChannelCount, Decoder, Source}; use rstest::rstest; use rstest_reuse::{self, *}; @@ -5,6 +8,17 @@ use std::io::{Read, Seek}; use std::path::Path; use std::time::Duration; +#[cfg(any( + feature = "flac", + feature = "minimp3", + feature = "symphonia-aac", + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[template] #[rstest] #[cfg_attr( @@ -37,6 +51,14 @@ fn all_decoders( ) { } +#[cfg(any( + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[template] #[rstest] #[cfg_attr( @@ -56,6 +78,16 @@ fn all_decoders( #[cfg_attr(feature = "symphonia-flac", case("flac", "symphonia"))] fn supported_decoders(#[case] format: &'static str, #[case] decoder_name: &'static str) {} +#[cfg(any( + feature = "flac", + feature = "minimp3", + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[apply(all_decoders)] #[trace] fn seek_returns_err_if_unsupported( @@ -68,6 +100,14 @@ fn seek_returns_err_if_unsupported( assert_eq!(res.is_ok(), supports_seek, "decoder: {decoder_name}"); } +#[cfg(any( + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[apply(supported_decoders)] #[trace] fn seek_beyond_end_saturates(#[case] format: &'static str, #[case] decoder_name: &'static str) { @@ -79,6 +119,14 @@ fn seek_beyond_end_saturates(#[case] format: &'static str, #[case] decoder_name: assert!(time_remaining(decoder) < Duration::from_secs(1)); } +#[cfg(any( + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[apply(supported_decoders)] #[trace] fn seek_results_in_correct_remaining_playtime( @@ -107,6 +155,14 @@ fn seek_results_in_correct_remaining_playtime( } } +#[cfg(any( + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[apply(supported_decoders)] #[trace] fn seek_possible_after_exausting_source( @@ -121,6 +177,14 @@ fn seek_possible_after_exausting_source( assert!(source.next().is_some()); } +#[cfg(any( + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[apply(supported_decoders)] #[trace] fn seek_does_not_break_channel_order( diff --git a/tests/total_duration.rs b/tests/total_duration.rs index 7298d661..0738c86d 100644 --- a/tests/total_duration.rs +++ b/tests/total_duration.rs @@ -1,3 +1,6 @@ +#![allow(dead_code)] +#![allow(unused_imports)] + use std::io::{Read, Seek}; use std::path::Path; use std::time::Duration; @@ -7,6 +10,17 @@ use rodio::{Decoder, Source}; use rstest::rstest; use rstest_reuse::{self, *}; +#[cfg(any( + feature = "flac", + feature = "minimp3", + feature = "symphonia-aac", + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[template] #[rstest] #[cfg_attr( @@ -61,6 +75,16 @@ fn get_music(format: &str) -> Decoder { .unwrap() } +#[cfg(any( + feature = "flac", + feature = "minimp3", + feature = "symphonia-flac", + feature = "symphonia-mp3", + feature = "symphonia-isomp4", + feature = "symphonia-ogg", + feature = "symphonia-wav", + feature = "wav", +))] #[apply(all_decoders)] #[trace] fn decoder_returns_total_duration( From 98a05831c4eca9881fa5c94a7ae029c4c9d3a0ed Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Tue, 3 Jun 2025 21:05:55 +0200 Subject: [PATCH 4/7] Add required-features constraints for examples and benchmarks Replaces conditional compilation with Cargo's required-features to ensure examples and benchmarks only compile when necessary features are available. Removes redundant cfg guards and fallback main functions from example files. --- Cargo.toml | 77 ++++++++++++++++++++++++++++-- examples/automatic_gain_control.rs | 9 ---- examples/basic.rs | 9 ---- examples/callback_on_end.rs | 9 ---- examples/custom_config.rs | 11 ----- examples/error_callback.rs | 10 ---- examples/low_pass.rs | 9 ---- examples/mix_multiple_sources.rs | 9 ---- examples/music_m4a.rs | 9 ---- examples/music_mp3.rs | 8 ---- examples/music_ogg.rs | 9 ---- examples/music_wav.rs | 9 ---- examples/noise_generator.rs | 8 ---- examples/reverb.rs | 9 ---- examples/seek_mp3.rs | 9 ---- examples/signal_generator.rs | 9 ---- examples/spatial.rs | 9 ---- examples/stereo.rs | 8 ---- 18 files changed, 72 insertions(+), 158 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 28d1cf01..6630b82e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,10 @@ minimp3_fixed = { version = "0.5.4", optional = true } symphonia = { version = "0.5.4", optional = true, default-features = false } crossbeam-channel = { version = "0.5.15", optional = true } -rand = { version = "0.9.0", features = ["small_rng", "os_rng"], optional = true } +rand = { version = "0.9.0", features = [ + "small_rng", + "os_rng", +], optional = true } tracing = { version = "0.1.40", optional = true } atomic_float = { version = "1.1.0", optional = true } @@ -72,27 +75,91 @@ divan = "0.1.14" [[bench]] name = "effects" harness = false +required-features = ["wav"] [[bench]] name = "conversions" harness = false +required-features = ["wav"] [[bench]] name = "resampler" harness = false +required-features = ["wav"] [[bench]] name = "pipeline" harness = false +required-features = ["wav"] + +[[example]] +name = "automatic_gain_control" +required-features = ["playback", "flac"] + +[[example]] +name = "basic" +required-features = ["playback", "vorbis"] + +[[example]] +name = "callback_on_end" +required-features = ["playback", "wav"] + +[[example]] +name = "custom_config" +required-features = ["playback", "wav"] + +[[example]] +name = "error_callback" +required-features = ["playback"] + +[[example]] +name = "into_file" +required-features = ["mp3", "wav"] + +[[example]] +name = "low_pass" +required-features = ["playback", "wav"] + +[[example]] +name = "mix_multiple_sources" +required-features = ["playback"] [[example]] name = "music_m4a" -required-features = ["symphonia-isomp4", "symphonia-aac"] +required-features = ["playback", "symphonia-isomp4", "symphonia-aac"] + +[[example]] +name = "music_mp3" +required-features = ["playback", "mp3"] + +[[example]] +name = "music_ogg" +required-features = ["playback", "vorbis"] + +[[example]] +name = "music_wav" +required-features = ["playback", "wav"] [[example]] name = "noise_generator" -required-features = ["noise"] +required-features = ["playback", "noise"] [[example]] -name = "into_file" -required-features = ["wav", "mp3"] +name = "reverb" +required-features = ["playback", "vorbis"] + +[[example]] +name = "seek_mp3" +required-features = ["playback", "mp3"] + +[[example]] +name = "signal_generator" +required-features = ["playback"] + +[[example]] +name = "spatial" +required-features = ["playback", "vorbis"] + +[[example]] +name = "stereo" +required-features = ["playback", "vorbis"] diff --git a/examples/automatic_gain_control.rs b/examples/automatic_gain_control.rs index bf027556..409fc73c 100644 --- a/examples/automatic_gain_control.rs +++ b/examples/automatic_gain_control.rs @@ -1,5 +1,3 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use rodio::source::Source; use rodio::Decoder; use std::error::Error; @@ -9,7 +7,6 @@ use std::sync::Arc; use std::thread; use std::time::Duration; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -49,9 +46,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/basic.rs b/examples/basic.rs index 0a2989fd..5628bd3b 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,5 +1,3 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use rodio::source::SineWave; use rodio::Source; use std::error::Error; @@ -7,7 +5,6 @@ use std::io::BufReader; use std::thread; use std::time::Duration; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let mixer = stream_handle.mixer(); @@ -53,9 +50,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/callback_on_end.rs b/examples/callback_on_end.rs index ad9184ae..f367f7f4 100644 --- a/examples/callback_on_end.rs +++ b/examples/callback_on_end.rs @@ -1,10 +1,7 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -39,9 +36,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/custom_config.rs b/examples/custom_config.rs index e931180a..4e1ff76a 100644 --- a/examples/custom_config.rs +++ b/examples/custom_config.rs @@ -1,8 +1,4 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - -#[cfg(feature = "playback")] use cpal::traits::HostTrait; -#[cfg(feature = "playback")] use cpal::{BufferSize, SampleFormat}; use rodio::source::SineWave; use rodio::Source; @@ -10,7 +6,6 @@ use std::error::Error; use std::thread; use std::time::Duration; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { // You can use any other output device that can be queried from CPAL. let default_device = cpal::default_host() @@ -38,9 +33,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/error_callback.rs b/examples/error_callback.rs index 7161532b..bb55ebdf 100644 --- a/examples/error_callback.rs +++ b/examples/error_callback.rs @@ -1,13 +1,9 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - -#[cfg(feature = "playback")] use cpal::traits::HostTrait; use rodio::source::SineWave; use rodio::Source; use std::error::Error; use std::time::Duration; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { // You can use any other output device that can be queried from CPAL. let default_device = cpal::default_host() @@ -43,9 +39,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/low_pass.rs b/examples/low_pass.rs index 853ec785..ec343888 100644 --- a/examples/low_pass.rs +++ b/examples/low_pass.rs @@ -1,11 +1,8 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; use std::io::BufReader; use rodio::Source; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -19,9 +16,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/mix_multiple_sources.rs b/examples/mix_multiple_sources.rs index 0681d0a3..75109c8b 100644 --- a/examples/mix_multiple_sources.rs +++ b/examples/mix_multiple_sources.rs @@ -1,11 +1,8 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use rodio::mixer; use rodio::source::{SineWave, Source}; use std::error::Error; use std::time::Duration; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { // Construct a dynamic controller and mixer, stream_handle, and sink. let (controller, mixer) = mixer::mixer(2, 44_100); @@ -42,9 +39,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/music_m4a.rs b/examples/music_m4a.rs index 8dd8afd5..ca7c4391 100644 --- a/examples/music_m4a.rs +++ b/examples/music_m4a.rs @@ -1,8 +1,5 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(&stream_handle.mixer()); @@ -14,9 +11,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/music_mp3.rs b/examples/music_mp3.rs index a9a254a3..43e17994 100644 --- a/examples/music_mp3.rs +++ b/examples/music_mp3.rs @@ -1,5 +1,3 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; #[cfg(feature = "playback")] @@ -14,9 +12,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/music_ogg.rs b/examples/music_ogg.rs index 43e9819e..f44dfec0 100644 --- a/examples/music_ogg.rs +++ b/examples/music_ogg.rs @@ -1,8 +1,5 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -14,9 +11,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/music_wav.rs b/examples/music_wav.rs index bd80a998..ea50de38 100644 --- a/examples/music_wav.rs +++ b/examples/music_wav.rs @@ -1,8 +1,5 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -14,9 +11,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/noise_generator.rs b/examples/noise_generator.rs index 0d73c1e6..03a8a5d5 100644 --- a/examples/noise_generator.rs +++ b/examples/noise_generator.rs @@ -1,9 +1,7 @@ //! Noise generator example. Use the "noise" feature to enable the noise generator sources. -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] use std::error::Error; -#[cfg(all(feature = "noise", feature = "playback"))] fn main() -> Result<(), Box> { use rodio::source::{pink, white, Source}; use std::thread; @@ -30,9 +28,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(all(feature = "noise", feature = "playback")))] -fn main() { - println!("rodio has not been compiled with noise sources, use `--features noise,playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/reverb.rs b/examples/reverb.rs index a9cd180e..b8c04b52 100644 --- a/examples/reverb.rs +++ b/examples/reverb.rs @@ -1,10 +1,7 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use rodio::Source; use std::error::Error; use std::time::Duration; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -18,9 +15,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/seek_mp3.rs b/examples/seek_mp3.rs index c977d009..c27f5346 100644 --- a/examples/seek_mp3.rs +++ b/examples/seek_mp3.rs @@ -1,9 +1,6 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; use std::time::Duration; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -25,9 +22,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/signal_generator.rs b/examples/signal_generator.rs index be7c5a07..d7f7537e 100644 --- a/examples/signal_generator.rs +++ b/examples/signal_generator.rs @@ -1,9 +1,6 @@ //! Test signal generator example. -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { use rodio::source::{chirp, Function, SignalGenerator, Source}; use std::thread; @@ -71,9 +68,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/spatial.rs b/examples/spatial.rs index 6946e6f6..f1b97e44 100644 --- a/examples/spatial.rs +++ b/examples/spatial.rs @@ -1,12 +1,9 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; use std::thread; use std::time::Duration; use rodio::Source; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let iter_duration = Duration::from_secs(5); let iter_distance = 5.; @@ -61,9 +58,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/stereo.rs b/examples/stereo.rs index 8a1315ed..c86eef73 100644 --- a/examples/stereo.rs +++ b/examples/stereo.rs @@ -1,10 +1,8 @@ //! Plays a tone alternating between right and left ears, with right being first. -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] use rodio::Source; use std::error::Error; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -16,9 +14,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} From 9549c01fa53efa337c9130a96062d4b0ca274a07 Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Tue, 3 Jun 2025 21:09:34 +0200 Subject: [PATCH 5/7] Remove feature gates from FLAC duration checks --- tests/flac_test.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/flac_test.rs b/tests/flac_test.rs index 3db4c1f2..39dd2fdd 100644 --- a/tests/flac_test.rs +++ b/tests/flac_test.rs @@ -1,6 +1,4 @@ -#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] use rodio::Source; -#[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] use std::time::Duration; #[cfg(any(feature = "flac", feature = "symphonia-flac"))] @@ -12,8 +10,6 @@ fn test_flac_encodings() { // File is not just silence assert!(decoder.any(|x| x != 0.0)); - // Symphonia does not expose functionality to get the duration so this check must be disabled - #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] assert_eq!(decoder.total_duration(), Some(Duration::from_secs(3))); // duration is calculated correctly // 24 bit FLAC file exported from Audacity (2 channels, various compression levels) @@ -21,7 +17,6 @@ fn test_flac_encodings() { let file = std::fs::File::open(format!("assets/audacity24bit_level{level}.flac")).unwrap(); let mut decoder = rodio::Decoder::try_from(file).unwrap(); assert!(!decoder.all(|x| x != 0.0)); - #[cfg(all(feature = "flac", not(feature = "symphonia-flac")))] assert_eq!(decoder.total_duration(), Some(Duration::from_secs(3))); } } From df8329b0788c23c614d909ba6450fbf26481d600 Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Tue, 3 Jun 2025 21:12:55 +0200 Subject: [PATCH 6/7] Clean up example code formatting and feature gates Remove unnecessary feature gates from music examples and fix minor formatting inconsistencies across example files. --- examples/automatic_gain_control.rs | 1 - examples/music_flac.rs | 9 --------- examples/music_mp3.rs | 1 - examples/signal_generator.rs | 1 + 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/examples/automatic_gain_control.rs b/examples/automatic_gain_control.rs index 409fc73c..884d046a 100644 --- a/examples/automatic_gain_control.rs +++ b/examples/automatic_gain_control.rs @@ -43,6 +43,5 @@ fn main() -> Result<(), Box> { // Keep the program running until the playback is complete. sink.sleep_until_end(); - Ok(()) } diff --git a/examples/music_flac.rs b/examples/music_flac.rs index 4a746b2a..f93028be 100644 --- a/examples/music_flac.rs +++ b/examples/music_flac.rs @@ -1,8 +1,5 @@ -#![cfg_attr(not(feature = "playback"), allow(unused_imports))] - use std::error::Error; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); @@ -14,9 +11,3 @@ fn main() -> Result<(), Box> { Ok(()) } - -#[cfg(not(feature = "playback"))] -fn main() { - println!("rodio has not been compiled with playback, use `--features playback` to enable this feature."); - println!("Exiting..."); -} diff --git a/examples/music_mp3.rs b/examples/music_mp3.rs index 43e17994..bacc7309 100644 --- a/examples/music_mp3.rs +++ b/examples/music_mp3.rs @@ -1,6 +1,5 @@ use std::error::Error; -#[cfg(feature = "playback")] fn main() -> Result<(), Box> { let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?; let sink = rodio::Sink::connect_new(stream_handle.mixer()); diff --git a/examples/signal_generator.rs b/examples/signal_generator.rs index d7f7537e..1ae4048e 100644 --- a/examples/signal_generator.rs +++ b/examples/signal_generator.rs @@ -1,4 +1,5 @@ //! Test signal generator example. + use std::error::Error; fn main() -> Result<(), Box> { From c407124d54709d5266ba5e9f96eba64d19adbb9c Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Tue, 3 Jun 2025 21:16:08 +0200 Subject: [PATCH 7/7] Add feature gates to FLAC test imports --- tests/flac_test.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/flac_test.rs b/tests/flac_test.rs index 39dd2fdd..be61bd75 100644 --- a/tests/flac_test.rs +++ b/tests/flac_test.rs @@ -1,4 +1,6 @@ +#[cfg(any(feature = "flac", feature = "symphonia-flac"))] use rodio::Source; +#[cfg(any(feature = "flac", feature = "symphonia-flac"))] use std::time::Duration; #[cfg(any(feature = "flac", feature = "symphonia-flac"))]