martin_core/
cache_zoom_range.rs1use serde::{Deserialize, Serialize};
4
5#[serde_with::skip_serializing_none]
8#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
9pub struct CacheZoomRange {
10 minzoom: Option<u8>,
11 maxzoom: Option<u8>,
12}
13
14impl CacheZoomRange {
15 #[must_use]
17 pub fn new(minzoom: Option<u8>, maxzoom: Option<u8>) -> Self {
18 Self { minzoom, maxzoom }
19 }
20
21 #[must_use]
24 pub fn disabled() -> Self {
25 Self {
26 minzoom: Some(u8::MAX),
27 maxzoom: Some(0),
28 }
29 }
30
31 #[must_use]
33 pub fn is_empty(self) -> bool {
34 self.minzoom.is_none() && self.maxzoom.is_none()
35 }
36
37 #[must_use]
40 pub fn contains(self, zoom: u8) -> bool {
41 self.minzoom.is_none_or(|m| zoom >= m) && self.maxzoom.is_none_or(|m| zoom <= m)
42 }
43
44 #[must_use]
46 pub fn or(self, other: Self) -> Self {
47 Self {
48 minzoom: self.minzoom.or(other.minzoom),
49 maxzoom: self.maxzoom.or(other.maxzoom),
50 }
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn disabled_never_contains() {
60 let disabled = CacheZoomRange::disabled();
61 assert!(!disabled.contains(0));
62 assert!(!disabled.contains(10));
63 assert!(!disabled.contains(u8::MAX));
64 }
65
66 #[test]
67 fn disabled_is_not_empty() {
68 assert!(!CacheZoomRange::disabled().is_empty());
69 }
70
71 #[test]
72 fn disabled_not_overridden_by_or() {
73 let disabled = CacheZoomRange::disabled();
74 let defaults = CacheZoomRange::new(Some(0), Some(20));
75 let merged = disabled.or(defaults);
77 assert!(!merged.contains(0));
78 assert!(!merged.contains(10));
79 }
80
81 #[test]
82 fn default_contains_all() {
83 let range = CacheZoomRange::default();
84 assert!(range.contains(0));
85 assert!(range.contains(u8::MAX));
86 }
87
88 #[test]
89 fn bounded_range() {
90 let range = CacheZoomRange::new(Some(2), Some(10));
91 assert!(!range.contains(1));
92 assert!(range.contains(2));
93 assert!(range.contains(10));
94 assert!(!range.contains(11));
95 }
96}