wsi-dicom 0.7.0

Convert whole-slide imaging files to DICOM VL Whole Slide Microscopy
Documentation
use std::time::{Duration, Instant};

use crate::error::Error;
use crate::time::duration_as_reported_micros;

#[derive(Clone, Copy)]
pub(super) struct RouteLevelDeadline {
    pub(super) started: Instant,
    pub(super) max_elapsed: Duration,
}

impl RouteLevelDeadline {
    pub(super) fn new(max_elapsed: Option<Duration>) -> Option<Self> {
        max_elapsed.map(|max_elapsed| Self {
            started: Instant::now(),
            max_elapsed,
        })
    }
}

pub(super) fn validate_max_level_elapsed(
    max_level_elapsed: Option<Duration>,
    context: &str,
) -> Result<(), Error> {
    if max_level_elapsed == Some(Duration::ZERO) {
        return Err(Error::Unsupported {
            reason: format!("{context} requires max_level_elapsed > 0 when provided"),
        });
    }
    Ok(())
}

pub(super) fn check_route_level_deadline(
    deadline: Option<RouteLevelDeadline>,
    level_idx: u32,
) -> Result<(), Error> {
    let Some(deadline) = deadline else {
        return Ok(());
    };
    let elapsed = deadline.started.elapsed();
    if elapsed > deadline.max_elapsed {
        return Err(Error::Unsupported {
            reason: format!(
                "route coverage level {level_idx} timed out after {:.3} ms (max_level_elapsed {:.3} ms)",
                duration_as_reported_micros(elapsed) as f64 / 1000.0,
                duration_as_reported_micros(deadline.max_elapsed) as f64 / 1000.0
            ),
        });
    }
    Ok(())
}