Skip to content

Commit 45c71b1

Browse files
committed
feat(float): add clamp
1 parent 91233a1 commit 45c71b1

7 files changed

Lines changed: 349 additions & 3 deletions

File tree

src/Core__Float.mjs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Generated by ReScript, PLEASE EDIT WITH CARE
22

3+
import * as Caml_obj from "rescript/lib/es6/caml_obj.js";
4+
import * as Caml_option from "rescript/lib/es6/caml_option.js";
35

46
var Constants = {};
57

@@ -26,10 +28,30 @@ function fromString(i) {
2628
}
2729
}
2830

31+
function clamp(min, max, value) {
32+
var value$1;
33+
if (max !== undefined) {
34+
var max$1 = Caml_option.valFromOption(max);
35+
value$1 = Caml_obj.lessthan(max$1, value) ? max$1 : value;
36+
} else {
37+
value$1 = value;
38+
}
39+
if (min === undefined) {
40+
return value$1;
41+
}
42+
var min$1 = Caml_option.valFromOption(min);
43+
if (Caml_obj.greaterthan(min$1, value$1)) {
44+
return min$1;
45+
} else {
46+
return value$1;
47+
}
48+
}
49+
2950
export {
3051
Constants ,
3152
equal ,
3253
compare ,
3354
fromString ,
55+
clamp ,
3456
}
3557
/* No side effect */

src/Core__Float.res

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,14 @@ external toInt: float => int = "%intoffloat"
4242
external fromInt: int => float = "%identity"
4343

4444
@unboxed @noalloc external mod: (float, float) => float = "?fmod_float"
45+
46+
let clamp = (~min=?, ~max=?, value) => {
47+
let value = switch max {
48+
| Some(max) if max < value => max
49+
| _ => value
50+
}
51+
switch min {
52+
| Some(min) if min > value => min
53+
| _ => value
54+
}
55+
}

src/Core__Float.resi

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,19 @@ Int.mod(7.0, 4.0) == 3
408408
```
409409
*/
410410
external mod: (float, float) => float = "?fmod_float"
411+
412+
/**
413+
`clamp(~min=?, ~max=?, value)` returns `value`, optionally bounded by `min` and `max`.
414+
415+
if `max` < `min` returns `min`.
416+
417+
## Examples
418+
419+
```rescript
420+
Int.clamp(4.2) == 4.2
421+
Int.clamp(4.2, ~min=4.3) == 4.3
422+
Int.clamp(4.2, ~max=4.1) == 4.1
423+
Int.clamp(4.2, ~min=4.3, ~max=4.1) == 4.3
424+
```
425+
*/
426+
let clamp: (~min: float=?, ~max: float=?, float) => float

test/FloatTests.mjs

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
// Generated by ReScript, PLEASE EDIT WITH CARE
2+
3+
import * as Test from "./Test.mjs";
4+
import * as Caml_obj from "rescript/lib/es6/caml_obj.js";
5+
import * as Pervasives from "rescript/lib/es6/pervasives.js";
6+
import * as Core__Float from "../src/Core__Float.mjs";
7+
8+
var eq = Caml_obj.equal;
9+
10+
Test.run([
11+
[
12+
"FloatTests.res",
13+
5,
14+
20,
15+
27
16+
],
17+
"clamp"
18+
], Core__Float.clamp(undefined, undefined, 4.2), eq, 4.2);
19+
20+
Test.run([
21+
[
22+
"FloatTests.res",
23+
6,
24+
20,
25+
35
26+
],
27+
"clamp - < min"
28+
], Core__Float.clamp(4.3, undefined, 4.1), eq, 4.3);
29+
30+
Test.run([
31+
[
32+
"FloatTests.res",
33+
7,
34+
20,
35+
35
36+
],
37+
"clamp - > min"
38+
], Core__Float.clamp(4.1, undefined, 4.2), eq, 4.2);
39+
40+
Test.run([
41+
[
42+
"FloatTests.res",
43+
8,
44+
20,
45+
35
46+
],
47+
"clamp - < max"
48+
], Core__Float.clamp(undefined, 4.3, 4.2), eq, 4.2);
49+
50+
Test.run([
51+
[
52+
"FloatTests.res",
53+
9,
54+
20,
55+
35
56+
],
57+
"clamp - > max"
58+
], Core__Float.clamp(undefined, 4.1, 4.2), eq, 4.1);
59+
60+
Test.run([
61+
[
62+
"FloatTests.res",
63+
10,
64+
20,
65+
42
66+
],
67+
"clamp - < min, < max"
68+
], Core__Float.clamp(4.3, 4.5, 4.2), eq, 4.3);
69+
70+
Test.run([
71+
[
72+
"FloatTests.res",
73+
11,
74+
20,
75+
42
76+
],
77+
"clamp - < min, > max"
78+
], Core__Float.clamp(4.3, 4.1, 4.2), eq, 4.3);
79+
80+
Test.run([
81+
[
82+
"FloatTests.res",
83+
12,
84+
20,
85+
42
86+
],
87+
"clamp - > min, < max"
88+
], Core__Float.clamp(4.1, 4.5, 4.2), eq, 4.2);
89+
90+
Test.run([
91+
[
92+
"FloatTests.res",
93+
13,
94+
20,
95+
42
96+
],
97+
"clamp - > min, > max"
98+
], Core__Float.clamp(4.1, 4.1, 4.2), eq, 4.1);
99+
100+
Test.run([
101+
[
102+
"FloatTests.res",
103+
14,
104+
20,
105+
33
106+
],
107+
"clamp - nan"
108+
], Core__Float.clamp(4.1, 4.3, Number.NaN), eq, 4.1);
109+
110+
Test.run([
111+
[
112+
"FloatTests.res",
113+
15,
114+
20,
115+
38
116+
],
117+
"clamp - infinity"
118+
], Core__Float.clamp(4.1, 4.3, Pervasives.infinity), eq, 4.3);
119+
120+
Test.run([
121+
[
122+
"FloatTests.res",
123+
16,
124+
20,
125+
39
126+
],
127+
"clamp - -infinity"
128+
], Core__Float.clamp(4.1, 4.3, Pervasives.neg_infinity), eq, 4.1);
129+
130+
Test.run([
131+
[
132+
"FloatTests.res",
133+
17,
134+
20,
135+
37
136+
],
137+
"clamp - min nan"
138+
], isNaN(Core__Float.clamp(Number.NaN, undefined, 4.2)), eq, true);
139+
140+
Test.run([
141+
[
142+
"FloatTests.res",
143+
18,
144+
20,
145+
37
146+
],
147+
"clamp - max nan"
148+
], Core__Float.clamp(undefined, Number.NaN, 4.2), eq, 4.2);
149+
150+
Test.run([
151+
[
152+
"FloatTests.res",
153+
20,
154+
13,
155+
39
156+
],
157+
"clamp - min nan, max nan"
158+
], isNaN(Core__Float.clamp(Number.NaN, Number.NaN, 4.2)), eq, true);
159+
160+
Test.run([
161+
[
162+
"FloatTests.res",
163+
25,
164+
20,
165+
42
166+
],
167+
"clamp - min infinity"
168+
], Core__Float.clamp(Pervasives.infinity, undefined, 4.2), eq, Pervasives.infinity);
169+
170+
Test.run([
171+
[
172+
"FloatTests.res",
173+
26,
174+
20,
175+
42
176+
],
177+
"clamp - max infinity"
178+
], Core__Float.clamp(undefined, Pervasives.infinity, 4.2), eq, 4.2);
179+
180+
Test.run([
181+
[
182+
"FloatTests.res",
183+
27,
184+
20,
185+
43
186+
],
187+
"clamp - min -infinity"
188+
], Core__Float.clamp(Pervasives.neg_infinity, undefined, 4.2), eq, 4.2);
189+
190+
Test.run([
191+
[
192+
"FloatTests.res",
193+
28,
194+
20,
195+
43
196+
],
197+
"clamp - max -infinity"
198+
], Core__Float.clamp(undefined, Pervasives.neg_infinity, 4.2), eq, Pervasives.neg_infinity);
199+
200+
Test.run([
201+
[
202+
"FloatTests.res",
203+
30,
204+
13,
205+
49
206+
],
207+
"clamp - min infinity, max infinity"
208+
], Core__Float.clamp(Pervasives.infinity, Pervasives.infinity, 4.2), eq, Pervasives.infinity);
209+
210+
Test.run([
211+
[
212+
"FloatTests.res",
213+
36,
214+
13,
215+
50
216+
],
217+
"clamp - min -infinity, max infinity"
218+
], Core__Float.clamp(Pervasives.neg_infinity, Pervasives.infinity, 4.2), eq, 4.2);
219+
220+
Test.run([
221+
[
222+
"FloatTests.res",
223+
42,
224+
13,
225+
50
226+
],
227+
"clamp - min infinity, max -infinity"
228+
], Core__Float.clamp(Pervasives.infinity, Pervasives.neg_infinity, 4.2), eq, Pervasives.infinity);
229+
230+
Test.run([
231+
[
232+
"FloatTests.res",
233+
48,
234+
13,
235+
51
236+
],
237+
"clamp - min -infinity, max -infinity"
238+
], Core__Float.clamp(Pervasives.neg_infinity, Pervasives.neg_infinity, 4.2), eq, Pervasives.neg_infinity);
239+
240+
export {
241+
eq ,
242+
}
243+
/* Not a pure module */

test/FloatTests.res

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
open RescriptCore
2+
3+
let eq = (a, b) => a == b
4+
5+
Test.run(__POS_OF__("clamp"), Float.clamp(4.2), eq, 4.2)
6+
Test.run(__POS_OF__("clamp - < min"), Float.clamp(~min=4.3, 4.1), eq, 4.3)
7+
Test.run(__POS_OF__("clamp - > min"), Float.clamp(~min=4.1, 4.2), eq, 4.2)
8+
Test.run(__POS_OF__("clamp - < max"), Float.clamp(~max=4.3, 4.2), eq, 4.2)
9+
Test.run(__POS_OF__("clamp - > max"), Float.clamp(~max=4.1, 4.2), eq, 4.1)
10+
Test.run(__POS_OF__("clamp - < min, < max"), Float.clamp(~min=4.3, ~max=4.5, 4.2), eq, 4.3)
11+
Test.run(__POS_OF__("clamp - < min, > max"), Float.clamp(~min=4.3, ~max=4.1, 4.2), eq, 4.3) // min wins
12+
Test.run(__POS_OF__("clamp - > min, < max"), Float.clamp(~min=4.1, ~max=4.5, 4.2), eq, 4.2)
13+
Test.run(__POS_OF__("clamp - > min, > max"), Float.clamp(~min=4.1, ~max=4.1, 4.2), eq, 4.1)
14+
Test.run(__POS_OF__("clamp - nan"), Float.clamp(~min=4.1, ~max=4.3, nan), eq, 4.1) // min wins ??
15+
Test.run(__POS_OF__("clamp - infinity"), Float.clamp(~min=4.1, ~max=4.3, infinity), eq, 4.3)
16+
Test.run(__POS_OF__("clamp - -infinity"), Float.clamp(~min=4.1, ~max=4.3, neg_infinity), eq, 4.1)
17+
Test.run(__POS_OF__("clamp - min nan"), Float.clamp(~min=nan, 4.2)->Float.isNaN, eq, true) // ??
18+
Test.run(__POS_OF__("clamp - max nan"), Float.clamp(~max=nan, 4.2), eq, 4.2)
19+
Test.run(
20+
__POS_OF__("clamp - min nan, max nan"),
21+
Float.clamp(~min=nan, ~max=nan, 4.2)->Float.isNaN,
22+
eq,
23+
true, // ??
24+
)
25+
Test.run(__POS_OF__("clamp - min infinity"), Float.clamp(~min=infinity, 4.2), eq, infinity)
26+
Test.run(__POS_OF__("clamp - max infinity"), Float.clamp(~max=infinity, 4.2), eq, 4.2)
27+
Test.run(__POS_OF__("clamp - min -infinity"), Float.clamp(~min=neg_infinity, 4.2), eq, 4.2)
28+
Test.run(__POS_OF__("clamp - max -infinity"), Float.clamp(~max=neg_infinity, 4.2), eq, neg_infinity)
29+
Test.run(
30+
__POS_OF__("clamp - min infinity, max infinity"),
31+
Float.clamp(~min=infinity, ~max=infinity, 4.2),
32+
eq,
33+
infinity,
34+
)
35+
Test.run(
36+
__POS_OF__("clamp - min -infinity, max infinity"),
37+
Float.clamp(~min=neg_infinity, ~max=infinity, 4.2),
38+
eq,
39+
4.2,
40+
)
41+
Test.run(
42+
__POS_OF__("clamp - min infinity, max -infinity"),
43+
Float.clamp(~min=infinity, ~max=neg_infinity, 4.2),
44+
eq,
45+
infinity, // min wins
46+
)
47+
Test.run(
48+
__POS_OF__("clamp - min -infinity, max -infinity"),
49+
Float.clamp(~min=neg_infinity, ~max=neg_infinity, 4.2),
50+
eq,
51+
neg_infinity,
52+
)

0 commit comments

Comments
 (0)