use serde::{Deserialize, Serialize};
#[serde_with::skip_serializing_none]
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct CacheZoomRange {
minzoom: Option<u8>,
maxzoom: Option<u8>,
}
impl CacheZoomRange {
#[must_use]
pub fn new(minzoom: Option<u8>, maxzoom: Option<u8>) -> Self {
Self { minzoom, maxzoom }
}
#[must_use]
pub fn disabled() -> Self {
Self {
minzoom: Some(u8::MAX),
maxzoom: Some(0),
}
}
#[must_use]
pub fn is_empty(self) -> bool {
self.minzoom.is_none() && self.maxzoom.is_none()
}
#[must_use]
pub fn contains(self, zoom: u8) -> bool {
self.minzoom.is_none_or(|m| zoom >= m) && self.maxzoom.is_none_or(|m| zoom <= m)
}
#[must_use]
pub fn or(self, other: Self) -> Self {
Self {
minzoom: self.minzoom.or(other.minzoom),
maxzoom: self.maxzoom.or(other.maxzoom),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn disabled_never_contains() {
let disabled = CacheZoomRange::disabled();
assert!(!disabled.contains(0));
assert!(!disabled.contains(10));
assert!(!disabled.contains(u8::MAX));
}
#[test]
fn disabled_is_not_empty() {
assert!(!CacheZoomRange::disabled().is_empty());
}
#[test]
fn disabled_not_overridden_by_or() {
let disabled = CacheZoomRange::disabled();
let defaults = CacheZoomRange::new(Some(0), Some(20));
let merged = disabled.or(defaults);
assert!(!merged.contains(0));
assert!(!merged.contains(10));
}
#[test]
fn default_contains_all() {
let range = CacheZoomRange::default();
assert!(range.contains(0));
assert!(range.contains(u8::MAX));
}
#[test]
fn bounded_range() {
let range = CacheZoomRange::new(Some(2), Some(10));
assert!(!range.contains(1));
assert!(range.contains(2));
assert!(range.contains(10));
assert!(!range.contains(11));
}
}