1use minecraft_command_types_derive::HasMacro;
2use ordered_float::NotNan;
3use std::fmt::{Display, Formatter};
4use std::ops::Range;
5
6#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
7pub struct IntegerRange {
8 pub min: Option<i32>,
9 pub max: Option<i32>,
10}
11
12impl IntegerRange {
13 pub fn new(min: Option<i32>, max: Option<i32>) -> IntegerRange {
14 if min.is_none() && max.is_none() {
15 panic!("min and/or max must be Some")
16 }
17
18 if let (Some(min), Some(max)) = (min, max)
19 && min > max
20 {
21 panic!("min must be smaller or equal to max");
22 }
23
24 IntegerRange { min, max }
25 }
26
27 pub fn new_min(min: i32) -> IntegerRange {
28 Self::new(Some(min), None)
29 }
30
31 pub fn new_max(max: i32) -> IntegerRange {
32 Self::new(None, Some(max))
33 }
34
35 pub fn new_min_max(min: i32, max: i32) -> IntegerRange {
36 Self::new(Some(min), Some(max))
37 }
38
39 pub fn new_single(value: i32) -> IntegerRange {
40 Self::new(Some(value), Some(value))
41 }
42}
43
44impl Display for IntegerRange {
45 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46 match (self.min, self.max) {
47 (Some(min), Some(max)) => {
48 if min == max {
49 Display::fmt(&min, f)
50 } else {
51 write!(f, "{}..{}", min, max)
52 }
53 }
54 (Some(min), None) => {
55 write!(f, "{}..", min)
56 }
57 (None, Some(max)) => {
58 write!(f, "..{}", max)
59 }
60 (None, None) => {
61 panic!("min and/or max must be Some")
62 }
63 }
64 }
65}
66
67impl From<(i32, i32)> for IntegerRange {
68 fn from(value: (i32, i32)) -> Self {
69 IntegerRange::new_min_max(value.0, value.1)
70 }
71}
72
73impl From<(Option<i32>, i32)> for IntegerRange {
74 fn from(value: (Option<i32>, i32)) -> Self {
75 IntegerRange::new(value.0, Some(value.1))
76 }
77}
78
79impl From<(i32, Option<i32>)> for IntegerRange {
80 fn from(value: (i32, Option<i32>)) -> Self {
81 IntegerRange::new(Some(value.0), value.1)
82 }
83}
84
85impl From<(Option<i32>, Option<i32>)> for IntegerRange {
86 fn from(value: (Option<i32>, Option<i32>)) -> Self {
87 IntegerRange::new(value.0, value.1)
88 }
89}
90
91impl From<Range<i32>> for IntegerRange {
92 fn from(value: Range<i32>) -> Self {
93 IntegerRange::new_min_max(value.start, value.end)
94 }
95}
96
97impl From<Range<Option<i32>>> for IntegerRange {
98 fn from(value: Range<Option<i32>>) -> Self {
99 IntegerRange::new(value.start, value.end)
100 }
101}
102
103#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
104pub struct FloatRange {
105 pub min: Option<NotNan<f32>>,
106 pub max: Option<NotNan<f32>>,
107}
108
109impl FloatRange {
110 #[must_use]
111 pub fn new(min: Option<NotNan<f32>>, max: Option<NotNan<f32>>) -> FloatRange {
112 if min.is_none() && max.is_none() {
113 panic!("min and/or max must be Some")
114 }
115
116 if let (Some(min), Some(max)) = (min, max)
117 && min > max
118 {
119 panic!("min must be smaller or equal to max");
120 }
121
122 FloatRange { min, max }
123 }
124
125 #[inline]
126 #[must_use]
127 pub fn new_min(min: NotNan<f32>) -> FloatRange {
128 Self::new(Some(min), None)
129 }
130
131 #[inline]
132 #[must_use]
133 pub fn new_max(max: NotNan<f32>) -> FloatRange {
134 Self::new(None, Some(max))
135 }
136
137 #[inline]
138 #[must_use]
139 pub fn new_min_max(min: NotNan<f32>, max: NotNan<f32>) -> FloatRange {
140 Self::new(Some(min), Some(max))
141 }
142
143 #[inline]
144 #[must_use]
145 pub fn new_single(value: NotNan<f32>) -> FloatRange {
146 Self::new(Some(value), Some(value))
147 }
148}
149
150impl Display for FloatRange {
151 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
152 match (self.min, self.max) {
153 (Some(min), Some(max)) => {
154 if min == max {
155 min.fmt(f)
156 } else {
157 write!(f, "{}..{}", min, max)
158 }
159 }
160 (Some(min), None) => {
161 write!(f, "{}..", min)
162 }
163 (None, Some(max)) => {
164 write!(f, "..{}", max)
165 }
166 (None, None) => {
167 panic!("min and/or max must be Some")
168 }
169 }
170 }
171}
172
173impl From<(NotNan<f32>, NotNan<f32>)> for FloatRange {
174 fn from(value: (NotNan<f32>, NotNan<f32>)) -> Self {
175 FloatRange::new_min_max(value.0, value.1)
176 }
177}
178
179impl From<(Option<NotNan<f32>>, NotNan<f32>)> for FloatRange {
180 fn from(value: (Option<NotNan<f32>>, NotNan<f32>)) -> Self {
181 FloatRange::new(value.0, Some(value.1))
182 }
183}
184
185impl From<(NotNan<f32>, Option<NotNan<f32>>)> for FloatRange {
186 fn from(value: (NotNan<f32>, Option<NotNan<f32>>)) -> Self {
187 FloatRange::new(Some(value.0), value.1)
188 }
189}
190
191impl From<(Option<NotNan<f32>>, Option<NotNan<f32>>)> for FloatRange {
192 fn from(value: (Option<NotNan<f32>>, Option<NotNan<f32>>)) -> Self {
193 FloatRange::new(value.0, value.1)
194 }
195}
196
197impl From<Range<NotNan<f32>>> for FloatRange {
198 fn from(value: Range<NotNan<f32>>) -> Self {
199 FloatRange::new_min_max(value.start, value.end)
200 }
201}
202
203impl From<Range<Option<NotNan<f32>>>> for FloatRange {
204 fn from(value: Range<Option<NotNan<f32>>>) -> Self {
205 FloatRange::new(value.start, value.end)
206 }
207}