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