rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

Suggest usage of `Ord::clamp`, `f32::clamp`, and `f64::clamp` to simplify code

Open Xaeroxe opened this issue 3 years ago • 1 comments

What it does

Identifies good opportunities for a clamp function from std or core, and suggests using it.

clamp functions

f32::clamp f64::clamp Ord::clamp

Lint Name

clamping_without_clamp

Category

complexity

Advantage

It's much shorter and easier to read, also doesn't use any control flow.

Drawbacks

The clamp functions panic in some circumstances which the original patterns will merely malfunction on. Namely, Ord types will panic if max < min and the floating point functions will additionally panic if min.is_nan() or max.is_nan(). Some may consider this a perk, but I'm listing it as a drawback because it may introduce panics where there weren't any before.

Example

if input > max {
    max
}
else if input < min {
    min
} else {
    input
}
input.max(min).min(max)
match input {
    input if input > max => max,
    input if input < min => min,
    input => input,
}

Could all be written as:

input.clamp(min, max)

Xaeroxe avatar Sep 14 '22 07:09 Xaeroxe

Another clamp anti-pattern

let mut x = input;
if x < min { x = min; }
if x > max { x = max; }

Should be

let x = input.clamp(min, max);

Xaeroxe avatar Sep 14 '22 22:09 Xaeroxe

Another anti-patten exists in chained min/max calls:

input.min(max).max(min)

and

input.max(min).min(max)

Should both be

input.clamp(min, max)

EDIT: ah, looks like this has been mentioned before: #5854 #6751

kylecarow avatar Jun 07 '24 18:06 kylecarow