From 0c1daf97a3cf09c586cc8ce00fa143459aa0ae85 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Tue, 18 May 2021 11:53:15 +0200 Subject: [PATCH 1/2] Implement is_finite for most types. is_finite (for num_traits::Float), is useful to detect NaNs and infinity when sanitizing inputs. --- src/angle.rs | 6 ++++++ src/box2d.rs | 10 +++++++++- src/box3d.rs | 10 +++++++++- src/point.rs | 16 ++++++++++++++++ src/rect.rs | 10 +++++++++- src/size.rs | 18 +++++++++++++++++- src/vector.rs | 12 ++++++++++++ 7 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/angle.rs b/src/angle.rs index c8f5a35..e24d860 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -109,6 +109,12 @@ where pub fn sin_cos(self) -> (T, T) { self.radians.sin_cos() } + + /// Returns true if the angle is a finite number. + #[inline] + pub fn is_finite(self) -> bool { + self.radians.is_finite() + } } impl Angle diff --git a/src/box2d.rs b/src/box2d.rs index a6464c6..36a4e3b 100644 --- a/src/box2d.rs +++ b/src/box2d.rs @@ -17,7 +17,7 @@ use crate::side_offsets::SideOffsets2D; use crate::size::Size2D; use crate::vector::{vec2, Vector2D}; -use num_traits::NumCast; +use num_traits::{NumCast, Float}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -571,6 +571,14 @@ impl Box2D { } } +impl Box2D { + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.min.is_finite() && self.max.is_finite() + } +} + impl Box2D where T: Round, diff --git a/src/box3d.rs b/src/box3d.rs index d99c2d4..7a5d9cd 100644 --- a/src/box3d.rs +++ b/src/box3d.rs @@ -15,7 +15,7 @@ use crate::scale::Scale; use crate::size::Size3D; use crate::vector::Vector3D; -use num_traits::NumCast; +use num_traits::{NumCast, Float}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -568,6 +568,14 @@ impl Box3D { } } +impl Box3D { + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.min.is_finite() && self.max.is_finite() + } +} + impl Box3D where T: Round, diff --git a/src/point.rs b/src/point.rs index e58dea3..8b72f07 100644 --- a/src/point.rs +++ b/src/point.rs @@ -485,6 +485,14 @@ impl Point2D { } } +impl Point2D { + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.x.is_finite() && self.y.is_finite() + } +} + impl, U> Point2D { #[inline] pub fn add_size(self, other: &Size2D) -> Self { @@ -1197,6 +1205,14 @@ impl Point3D { } } +impl Point3D { + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.x.is_finite() && self.y.is_finite() && self.z.is_finite() + } +} + impl, U> Point3D { #[inline] pub fn add_size(self, other: Size3D) -> Self { diff --git a/src/rect.rs b/src/rect.rs index 15aa926..289ff7a 100644 --- a/src/rect.rs +++ b/src/rect.rs @@ -16,7 +16,7 @@ use crate::side_offsets::SideOffsets2D; use crate::size::Size2D; use crate::vector::Vector2D; -use num_traits::NumCast; +use num_traits::{NumCast, Float}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -594,6 +594,14 @@ impl Rect { } } +impl Rect { + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.origin.is_finite() && self.size.is_finite() + } +} + impl + Sub, U> Rect { /// Return a rectangle with edges rounded to integer coordinates, such that /// the returned rectangle has the same set of pixel centers as the original diff --git a/src/size.rs b/src/size.rs index 5ad0902..36b7fcd 100644 --- a/src/size.rs +++ b/src/size.rs @@ -23,7 +23,7 @@ use core::hash::Hash; use core::iter::Sum; use core::marker::PhantomData; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; -use num_traits::{NumCast, Signed}; +use num_traits::{NumCast, Signed, Float}; #[cfg(feature = "serde")] use serde; @@ -392,6 +392,14 @@ impl Size2D { } } +impl Size2D { + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.width.is_finite() && self.height.is_finite() + } +} + impl Size2D { /// Computes the absolute value of each component. /// @@ -1273,6 +1281,14 @@ impl Size3D { } } +impl Size3D { + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.width.is_finite() && self.height.is_finite() && self.depth.is_finite() + } +} + impl Size3D { /// Computes the absolute value of each component. /// diff --git a/src/vector.rs b/src/vector.rs index f1a09ab..9e180b6 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -509,6 +509,12 @@ impl Vector2D { debug_assert!(min <= max); self.with_min_length(min).with_max_length(max) } + + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.x.is_finite() && self.y.is_finite() + } } impl Vector2D @@ -1353,6 +1359,12 @@ impl Vector3D { debug_assert!(min <= max); self.with_min_length(min).with_max_length(max) } + + /// Returns true if all members are finite. + #[inline] + pub fn is_finite(self) -> bool { + self.x.is_finite() && self.y.is_finite() && self.z.is_finite() + } } impl Vector3D From 22ef9b3e7f9a78edd8f0bcc1f650d977f82f991a Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Tue, 18 May 2021 11:54:19 +0200 Subject: [PATCH 2/2] Version 0.22.4. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e97ddba..12c0c55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "euclid" -version = "0.22.3" +version = "0.22.4" authors = ["The Servo Project Developers"] edition = "2018" description = "Geometry primitives"