1use crate::constants::MAX_ZOOM;
3use serde::Serialize;
4use std::num::ParseIntError;
5use std::ops::BitAnd;
6
7use crate::errors::UtilesCoreResult;
8use crate::UtilesCoreError;
9use crate::UtilesCoreError::InvalidZoom;
10
11#[must_use]
13pub fn zoom_max_xy(zoom: u8) -> u32 {
14 2_u32.pow(u32::from(zoom)) - 1
15}
16
17#[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Serialize)]
36pub struct ZoomSet(u32);
37
38#[must_use]
56pub fn zset2zvec(zset: u32) -> Vec<u8> {
57 if zset & (1 << 31) != 0 {
59 zset2zvec(zset.reverse_bits() >> 1)
60 } else {
61 (0u8..31).filter(|&i| (zset & (1u32 << i)) != 0).collect()
62 }
63}
64
65#[must_use]
75pub fn zvec2zset(zvec: &[u8]) -> u32 {
76 zvec.iter().fold(0, |acc, &z| acc | (1 << z))
77}
78
79#[must_use]
82pub fn zset2zvec_rev(zset: u32) -> Vec<u8> {
83 zset2zvec(zset.reverse_bits() >> 1)
84}
85
86#[must_use]
88pub fn zvec2zset_rev(zvec: &[u8]) -> u32 {
89 zvec.iter().fold(0, |acc, &z| acc | (1 << (31 - z)))
90}
91
92impl ZoomSet {
94 #[must_use]
96 pub fn new(zset: u32) -> Self {
97 Self(zset)
98 }
99
100 #[must_use]
102 pub fn from_zooms(zooms: &[u8]) -> Self {
103 Self(zvec2zset(zooms))
104 }
105
106 #[must_use]
108 pub fn to_zooms(&self) -> Vec<u8> {
109 zset2zvec(self.0)
110 }
111
112 #[must_use]
113 pub fn all() -> Self {
114 Self(0b0111_1111_1111_1111_1111_1111_1111_1111)
115 }
116
117 #[must_use]
118 pub fn zoom_ranges(&self) -> Vec<ZoomRange> {
119 let mut ranges: Vec<ZoomRange> = vec![];
120 let mut min: u8 = 0;
121 let mut max: u8 = 0;
122 let mut i: u8 = 0;
123 while i < MAX_ZOOM {
124 if self.0 & (1 << i) != 0 {
125 if min == 0 {
126 min = i;
127 }
128 max = i;
129 } else if min != 0 {
130 ranges.push(ZoomRange::new(min, max));
131 min = 0;
132 max = 0;
133 }
134 i += 1;
135 }
136 if min != 0 {
137 ranges.push(ZoomRange::new(min, max));
138 }
139 ranges
140 }
141}
142
143impl From<u8> for ZoomSet {
144 fn from(zoom: u8) -> Self {
145 ZoomSet(1 << zoom)
146 }
147}
148
149impl From<u32> for ZoomSet {
150 fn from(zset: u32) -> Self {
151 ZoomSet(zset)
152 }
153}
154
155impl From<ZoomSet> for Vec<u8> {
156 fn from(zset: ZoomSet) -> Self {
157 zset2zvec(zset.0)
158 }
159}
160
161impl TryFrom<Vec<u8>> for ZoomSet {
162 type Error = UtilesCoreError;
163
164 fn try_from(zvec: Vec<u8>) -> Result<Self, Self::Error> {
165 let result = zvec.iter().try_fold(0u32, |acc, &z| {
166 if z > MAX_ZOOM {
167 Err(InvalidZoom(z.to_string()))
168 } else {
169 Ok(acc | (1 << z))
170 }
171 })?;
172 Ok(ZoomSet::new(result)) }
174}
175
176impl BitAnd for ZoomSet {
177 type Output = ZoomSet;
178
179 fn bitand(self, rhs: Self) -> Self::Output {
180 ZoomSet(self.0 & rhs.0)
181 }
182}
183
184impl BitAnd<u32> for ZoomSet {
185 type Output = ZoomSet;
186
187 fn bitand(self, rhs: u32) -> Self::Output {
188 ZoomSet(self.0 & rhs)
189 }
190}
191
192impl BitAnd<ZoomSet> for u32 {
193 type Output = ZoomSet;
194
195 fn bitand(self, rhs: ZoomSet) -> Self::Output {
196 ZoomSet(self & rhs.0)
197 }
198}
199
200impl BitAnd<u8> for ZoomSet {
201 type Output = ZoomSet;
202
203 fn bitand(self, rhs: u8) -> Self::Output {
204 ZoomSet(self.0 & (1 << (31 - rhs)))
205 }
206}
207
208type ZoomsSetInt = u32;
209
210#[derive(Debug, Clone, Eq, PartialEq)]
212pub struct ZoomRange {
213 pub min: u8,
215 pub max: u8,
217}
218
219impl Default for ZoomRange {
221 fn default() -> Self {
222 Self {
223 min: 0,
224 max: MAX_ZOOM,
225 }
226 }
227}
228
229impl ZoomRange {
230 #[must_use]
232 pub fn new(min: u8, max: u8) -> Self {
233 Self { min, max }
234 }
235
236 #[must_use]
238 pub fn from_max(max: u8) -> Self {
239 Self { min: 0, max }
240 }
241
242 #[must_use]
244 pub fn from_min(min: u8) -> Self {
245 Self { min, max: 30 }
246 }
247}
248
249impl IntoIterator for ZoomRange {
250 type Item = u8;
251 type IntoIter = std::ops::RangeInclusive<u8>;
252
253 fn into_iter(self) -> Self::IntoIter {
254 self.min..=self.max
255 }
256}
257
258impl From<ZoomRange> for ZoomSet {
268 fn from(zoom_range: ZoomRange) -> Self {
269 ZoomSet(zoom_range.into_iter().fold(0, |acc, z| acc | (1 << z)))
270 }
271}
272
273pub fn parse_zooms(zstr: &str) -> UtilesCoreResult<Vec<u8>> {
287 let mut zvec: Vec<u8> = vec![];
288 for z in zstr.split(',') {
289 if z.contains('-') {
290 let zrange: Result<Vec<u8>, ParseIntError> =
291 z.split('-').map(str::parse).collect::<Result<Vec<_>, _>>();
292
293 let zrange = match zrange {
294 Ok(zrange) => match zrange.len() {
295 1 => vec![zrange[0]],
296 2 => (zrange[0]..=zrange[1]).collect(),
297 _ => vec![],
298 },
299 Err(_) => return Err(InvalidZoom(z.to_string())),
300 };
301 zvec.extend(zrange);
302 } else {
303 match z.parse::<u8>() {
304 Ok(num) => zvec.push(num),
305 Err(_) => return Err(InvalidZoom(z.to_string())),
306 }
307 }
308 }
309 for z in &zvec {
311 if *z > 32 {
312 return Err(InvalidZoom((*z).to_string()));
313 }
314 }
315 zvec.sort_unstable();
317 zvec.dedup();
318 Ok(zvec)
319}
320
321pub enum ZoomOrZooms {
323 Zoom(u8),
325
326 Zooms(Vec<u8>),
328}
329
330impl From<u8> for ZoomOrZooms {
331 fn from(zoom: u8) -> Self {
332 ZoomOrZooms::Zoom(zoom)
333 }
334}
335
336impl From<Vec<u8>> for ZoomOrZooms {
337 fn from(zooms: Vec<u8>) -> Self {
338 ZoomOrZooms::Zooms(zooms)
339 }
340}
341
342impl From<ZoomOrZooms> for ZoomsSetInt {
343 fn from(zoom_or_zooms: ZoomOrZooms) -> Self {
344 match zoom_or_zooms {
345 ZoomOrZooms::Zoom(zoom) => 1 << (31 - zoom),
346 ZoomOrZooms::Zooms(zooms) => zvec2zset_rev(&zooms),
347 }
348 }
349}
350
351#[cfg(test)]
352mod tests {
353 use super::*;
354
355 #[test]
356 fn zset2zvec_none() {
357 let zset: u32 = 0b0000_0000_0000_0000_0000_0000_0000_0000;
358 let zvec: Vec<u8> = vec![];
359 assert_eq!(zset2zvec(zset), zvec);
360 assert_eq!(zset2zvec_rev(zset), zvec);
361 assert_eq!(zset, 0);
362 }
363
364 #[test]
365 fn zset2zvec_0_1_2() {
366 let zset_fwd: u32 = 0b0000_0000_0000_0000_0000_0000_0000_0111;
367 let zset_rev: u32 = 0b1111_0000_0000_0000_0000_0000_0000_0000;
368 let zvec: Vec<u8> = vec![0, 1, 2];
369 assert_eq!(zset2zvec(zset_fwd), zvec);
370 assert_eq!(zset_fwd, 7);
371 assert_eq!(zset2zvec_rev(zset_rev), zvec);
372 }
373
374 #[test]
375 fn zset2zvec_all() {
376 let zset_int_fwd: u32 = 0b0111_1111_1111_1111_1111_1111_1111_1111;
377 let zset_int_rev: u32 = 0b1111_1111_1111_1111_1111_1111_1111_1111;
378 let zvec: Vec<u8> = vec![
379 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
380 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
381 ];
382 assert_eq!(zset2zvec(zset_int_fwd), zvec);
383 assert_eq!(zset2zvec_rev(zset_int_rev), zvec);
384 }
385
386 #[test]
387 fn zvec2zset_none() {
388 let zset_int: u32 = 0b0000_0000_0000_0000_0000_0000_0000_0000;
389 assert!(zset2zvec(zset_int).is_empty());
390 assert!(zset2zvec_rev(zset_int).is_empty());
391 }
392
393 #[test]
394 fn zvec2zset_0_1_2() {
395 let zset_int: u32 = 0b1110_0000_0000_0000_0000_0000_0000_0000;
396 let zvec: Vec<u8> = vec![0, 1, 2];
397
398 assert_eq!(zvec2zset_rev(&zvec), zset_int);
399 }
400
401 #[test]
402 fn zvec2zset_0_1_2_3_4_5_6_7() {
403 let zset_int: u32 = 0b1111_1111_0000_0000_0000_0000_0000_0000;
404 let zvec: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7];
405 let zset_from_zvec = zvec2zset_rev(&zvec);
406 assert_eq!(zset_from_zvec, zset_int);
407 }
408
409 #[test]
410 fn zoom_set_into_zoom_vec() {
411 let zset_int_fwd: u32 = 0b0000_0000_0000_0000_0000_0000_1111_1111;
412 let zet_fwd_vec: Vec<u8> = ZoomSet::from(zset_int_fwd).into();
413 assert_eq!(zet_fwd_vec, vec![0, 1, 2, 3, 4, 5, 6, 7]);
414 let zset_int_rev: u32 = 0b1111_1111_1000_0000_0000_0000_0000_0000;
415 let zset: ZoomSet = zset_int_rev.into();
416 let zvec = Vec::from(zset);
417 assert_eq!(zvec, vec![0, 1, 2, 3, 4, 5, 6, 7]);
418 }
419}