#[cfg(feature = "progress")]
use crate::error::Result;
#[cfg(feature = "progress")]
macro_rules! emit_progress {
($progress:expr, $snapshot:expr) => {{
#[cfg(feature = "progress")]
{
$progress.on_frame($snapshot)
}
#[cfg(not(feature = "progress"))]
{
let _ = $progress;
Ok::<(), crate::error::Error>(())
}
}};
}
#[cfg(feature = "progress")]
pub(crate) use emit_progress;
#[cfg(feature = "progress")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ProgressSnapshot {
pub processed_samples: u64,
pub total_samples: u64,
pub completed_frames: usize,
pub total_frames: usize,
pub input_bytes_read: u64,
pub output_bytes_written: u64,
}
#[cfg(feature = "progress")]
pub type EncodeProgress = ProgressSnapshot;
#[cfg(feature = "progress")]
pub type DecodeProgress = ProgressSnapshot;
#[cfg(feature = "progress")]
pub(crate) trait ProgressSink {
fn on_frame(&mut self, progress: ProgressSnapshot) -> Result<()>;
}
#[cfg(not(feature = "progress"))]
pub(crate) trait ProgressSink {}
pub(crate) struct NoProgress;
#[cfg(feature = "progress")]
impl ProgressSink for NoProgress {
fn on_frame(&mut self, _progress: ProgressSnapshot) -> Result<()> {
Ok(())
}
}
#[cfg(not(feature = "progress"))]
impl ProgressSink for NoProgress {}
#[cfg(feature = "progress")]
pub(crate) struct CallbackProgress<F> {
callback: F,
}
#[cfg(feature = "progress")]
impl<F> CallbackProgress<F> {
pub(crate) fn new(callback: F) -> Self {
Self { callback }
}
}
#[cfg(feature = "progress")]
impl<F> ProgressSink for CallbackProgress<F>
where
F: FnMut(ProgressSnapshot) -> Result<()>,
{
fn on_frame(&mut self, progress: ProgressSnapshot) -> Result<()> {
(self.callback)(progress)
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "progress")]
use super::ProgressSnapshot;
#[cfg(feature = "progress")]
#[test]
fn progress_snapshot_carries_input_bytes_read_and_output_bytes_written() {
let snapshot = ProgressSnapshot {
processed_samples: 128,
total_samples: 256,
completed_frames: 2,
total_frames: 4,
input_bytes_read: 4_096,
output_bytes_written: 1_024,
};
assert_eq!(snapshot.input_bytes_read, 4_096);
assert_eq!(snapshot.output_bytes_written, 1_024);
}
#[cfg(not(feature = "progress"))]
#[test]
fn progress_types_are_not_reexported_without_progress_feature() {
let _ = crate::Error::Encode("no progress".into());
}
}