kasane_logic/spatial_id/range_id/
random.rs1use crate::RangeId;
2
3#[cfg(any(test))]
4use proptest::prelude::Strategy;
5#[cfg(any(test, feature = "random"))]
6use rand::Rng;
7#[cfg(any(test, feature = "random"))]
8use std::ops::RangeInclusive;
9
10impl RangeId {
11 #[cfg(any(test, feature = "random"))]
12 fn pick_zoom_using<R: Rng>(rng: &mut R, z_range: RangeInclusive<u8>) -> u8 {
13 use crate::MAX_ZOOM_LEVEL;
14
15 let start = *z_range.start();
16 let end = (*z_range.end()).min(MAX_ZOOM_LEVEL as u8);
17
18 if start > end {
19 end
20 } else {
21 rng.random_range(start..=end)
22 }
23 }
24
25 #[cfg(any(test, feature = "random"))]
27 pub fn random_using<R: Rng>(rng: &mut R) -> Self {
28 use crate::MAX_ZOOM_LEVEL;
29
30 Self::random_within_using(rng, 0..=MAX_ZOOM_LEVEL as u8)
31 }
32
33 #[cfg(any(test, feature = "random"))]
35 pub fn random_at_using<R: Rng>(rng: &mut R, z: u8) -> Self {
36 Self::random_within_using(rng, z..=z)
37 }
38
39 #[cfg(any(test, feature = "random"))]
41 pub fn random_within_using<R: Rng>(rng: &mut R, z_range: RangeInclusive<u8>) -> Self {
42 use crate::{F_MAX, F_MIN, XY_MAX};
43
44 let z = Self::pick_zoom_using(rng, z_range);
45 let z_idx = z as usize;
46
47 let f_min = F_MIN[z_idx];
48 let f_max = F_MAX[z_idx];
49 let xy_max = XY_MAX[z_idx];
50
51 let f1 = rng.random_range(f_min..=f_max);
53 let f2 = rng.random_range(f_min..=f_max);
54
55 let x1 = rng.random_range(0..=xy_max);
56 let x2 = rng.random_range(0..=xy_max);
57
58 let y1 = rng.random_range(0..=xy_max);
59 let y2 = rng.random_range(0..=xy_max);
60
61 RangeId::new(z, [f1, f2], [x1, x2], [y1, y2])
63 .expect("Generated parameters should be always valid")
64 }
65
66 #[cfg(any(test, feature = "random"))]
68 pub fn random() -> Self {
69 let mut rng = rand::rng();
70 Self::random_using(&mut rng)
71 }
72
73 #[cfg(any(test, feature = "random"))]
75 pub fn random_at(z: u8) -> Self {
76 let mut rng = rand::rng();
77 Self::random_at_using(&mut rng, z)
78 }
79
80 #[cfg(any(test, feature = "random"))]
84 pub fn random_within(z_range: RangeInclusive<u8>) -> Self {
85 let mut rng = rand::rng();
86 Self::random_within_using(&mut rng, z_range)
87 }
88
89 #[cfg(any(test))]
91 pub fn arb() -> impl Strategy<Value = Self> {
92 use crate::MAX_ZOOM_LEVEL;
93
94 Self::arb_within(0..=MAX_ZOOM_LEVEL as u8)
95 }
96
97 #[cfg(any(test))]
99 pub fn arb_at(z: u8) -> impl Strategy<Value = Self> {
100 Self::arb_within(z..=z)
101 }
102
103 #[cfg(any(test))]
107 pub fn arb_within(z_range: RangeInclusive<u8>) -> impl Strategy<Value = Self> {
108 use crate::MAX_ZOOM_LEVEL;
109
110 let start = *z_range.start();
111 let end = (*z_range.end()).min(MAX_ZOOM_LEVEL as u8);
112 let (start, end) = if start > end {
113 (end, end)
114 } else {
115 (start, end)
116 };
117
118 (start..=end).prop_flat_map(|z| {
119 use proptest::prelude::Just;
120
121 use crate::{F_MAX, F_MIN, XY_MAX};
122
123 let z_idx = z as usize;
124
125 let f_min = F_MIN[z_idx];
126 let f_max = F_MAX[z_idx];
127 let xy_max = XY_MAX[z_idx];
128
129 let f_strat = (f_min..=f_max, f_min..=f_max);
130 let x_strat = (0..=xy_max, 0..=xy_max);
131 let y_strat = (0..=xy_max, 0..=xy_max);
132
133 (Just(z), f_strat, x_strat, y_strat).prop_map(
134 move |(z, (f1, f2), (x1, x2), (y1, y2))| {
135 RangeId::new(z, [f1, f2], [x1, x2], [y1, y2])
136 .expect("Generated parameters should be always valid")
137 },
138 )
139 })
140 }
141}