#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DestinationState {
Available,
Archived,
Resumed,
SizeMismatch { expected: u64, actual: u64 },
}
#[allow(dead_code)] impl DestinationState {
pub fn needs_transfer(&self) -> bool {
matches!(self, DestinationState::Available)
}
pub fn is_error(&self) -> bool {
matches!(self, DestinationState::SizeMismatch { .. })
}
}
pub fn classify_destination(
in_db: bool,
on_disk: Option<u64>,
expected_size: u64,
) -> DestinationState {
if in_db {
DestinationState::Archived
} else if let Some(actual_size) = on_disk {
if actual_size == expected_size {
DestinationState::Resumed
} else {
DestinationState::SizeMismatch {
expected: expected_size,
actual: actual_size,
}
}
} else {
DestinationState::Available
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn classify_not_in_db_not_on_disk() {
let state = classify_destination(false, None, 1024);
assert_eq!(state, DestinationState::Available);
assert!(state.needs_transfer());
assert!(!state.is_error());
}
#[test]
fn classify_in_db() {
let state = classify_destination(true, None, 1024);
assert_eq!(state, DestinationState::Archived);
assert!(!state.needs_transfer());
assert!(!state.is_error());
let state = classify_destination(true, Some(1024), 1024);
assert_eq!(state, DestinationState::Archived);
}
#[test]
fn classify_on_disk_size_matches() {
let state = classify_destination(false, Some(1024), 1024);
assert_eq!(state, DestinationState::Resumed);
assert!(!state.needs_transfer());
assert!(!state.is_error());
}
#[test]
fn classify_on_disk_size_smaller() {
let state = classify_destination(false, Some(512), 1024);
assert_eq!(
state,
DestinationState::SizeMismatch {
expected: 1024,
actual: 512
}
);
assert!(!state.needs_transfer());
assert!(state.is_error());
}
#[test]
fn classify_on_disk_size_larger() {
let state = classify_destination(false, Some(2048), 1024);
assert_eq!(
state,
DestinationState::SizeMismatch {
expected: 1024,
actual: 2048
}
);
assert!(!state.needs_transfer());
assert!(state.is_error());
}
}