From ee8d415c4fabdc2e4b495080d86f30cace7f2085 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 7 Jun 2018 19:52:59 +0200 Subject: [PATCH] Make cast infallible and add try_cast. --- src/length.rs | 9 +++++++-- src/point.rs | 47 +++++++++++++++++++++++++++++++-------------- src/rect.rs | 28 +++++++++++++++++++-------- src/scale.rs | 7 ++++++- src/size.rs | 23 +++++++++++++++------- src/transform2d.rs | 15 +++++++++++---- src/transform3d.rs | 7 ++++++- src/vector.rs | 48 ++++++++++++++++++++++++++++++++-------------- 8 files changed, 133 insertions(+), 51 deletions(-) diff --git a/src/length.rs b/src/length.rs index d4f44fb2..ed7f9172 100644 --- a/src/length.rs +++ b/src/length.rs @@ -211,7 +211,12 @@ impl> Neg for Length { impl Length { /// Cast from one numeric representation to another, preserving the units. - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> Length { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + pub fn try_cast(&self) -> Option> { NumCast::from(self.get()).map(Length::new) } } @@ -461,7 +466,7 @@ mod tests { fn test_cast() { let length_as_i32: Length = Length::new(5); - let result: Length = length_as_i32.cast().unwrap(); + let result: Length = length_as_i32.cast(); let length_as_f32: Length = Length::new(5.0); assert_eq!(result, length_as_f32); diff --git a/src/point.rs b/src/point.rs index 4f2e5d27..b42e25d7 100644 --- a/src/point.rs +++ b/src/point.rs @@ -286,7 +286,16 @@ impl TypedPoint2D { /// as one would expect from a simple cast, but this behavior does not always make sense /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. #[inline] - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> TypedPoint2D { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + /// + /// When casting from floating point to integer coordinates, the decimals are truncated + /// as one would expect from a simple cast, but this behavior does not always make sense + /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. + pub fn try_cast(&self) -> Option> { match (NumCast::from(self.x), NumCast::from(self.y)) { (Some(x), Some(y)) => Some(point2(x, y)), _ => None, @@ -298,13 +307,13 @@ impl TypedPoint2D { /// Cast into an `f32` point. #[inline] pub fn to_f32(&self) -> TypedPoint2D { - self.cast().unwrap() + self.cast() } /// Cast into an `f64` point. #[inline] pub fn to_f64(&self) -> TypedPoint2D { - self.cast().unwrap() + self.cast() } /// Cast into an `usize` point, truncating decimals if any. @@ -314,7 +323,7 @@ impl TypedPoint2D { /// the desired conversion behavior. #[inline] pub fn to_usize(&self) -> TypedPoint2D { - self.cast().unwrap() + self.cast() } /// Cast into an `u32` point, truncating decimals if any. @@ -324,7 +333,7 @@ impl TypedPoint2D { /// the desired conversion behavior. #[inline] pub fn to_u32(&self) -> TypedPoint2D { - self.cast().unwrap() + self.cast() } /// Cast into an i32 point, truncating decimals if any. @@ -334,7 +343,7 @@ impl TypedPoint2D { /// the desired conversion behavior. #[inline] pub fn to_i32(&self) -> TypedPoint2D { - self.cast().unwrap() + self.cast() } /// Cast into an i64 point, truncating decimals if any. @@ -344,7 +353,7 @@ impl TypedPoint2D { /// the desired conversion behavior. #[inline] pub fn to_i64(&self) -> TypedPoint2D { - self.cast().unwrap() + self.cast() } } @@ -650,7 +659,17 @@ impl TypedPoint3D { /// as one would expect from a simple cast, but this behavior does not always make sense /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. #[inline] - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> TypedPoint3D { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + /// + /// When casting from floating point to integer coordinates, the decimals are truncated + /// as one would expect from a simple cast, but this behavior does not always make sense + /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. + #[inline] + pub fn try_cast(&self) -> Option> { match ( NumCast::from(self.x), NumCast::from(self.y), @@ -666,13 +685,13 @@ impl TypedPoint3D { /// Cast into an `f32` point. #[inline] pub fn to_f32(&self) -> TypedPoint3D { - self.cast().unwrap() + self.cast() } /// Cast into an `f64` point. #[inline] pub fn to_f64(&self) -> TypedPoint3D { - self.cast().unwrap() + self.cast() } /// Cast into an `usize` point, truncating decimals if any. @@ -682,7 +701,7 @@ impl TypedPoint3D { /// the desired conversion behavior. #[inline] pub fn to_usize(&self) -> TypedPoint3D { - self.cast().unwrap() + self.cast() } /// Cast into an `u32` point, truncating decimals if any. @@ -692,7 +711,7 @@ impl TypedPoint3D { /// the desired conversion behavior. #[inline] pub fn to_u32(&self) -> TypedPoint3D { - self.cast().unwrap() + self.cast() } /// Cast into an `i32` point, truncating decimals if any. @@ -702,7 +721,7 @@ impl TypedPoint3D { /// the desired conversion behavior. #[inline] pub fn to_i32(&self) -> TypedPoint3D { - self.cast().unwrap() + self.cast() } /// Cast into an `i64` point, truncating decimals if any. @@ -712,7 +731,7 @@ impl TypedPoint3D { /// the desired conversion behavior. #[inline] pub fn to_i64(&self) -> TypedPoint3D { - self.cast().unwrap() + self.cast() } } diff --git a/src/rect.rs b/src/rect.rs index 3fb67566..01437d04 100644 --- a/src/rect.rs +++ b/src/rect.rs @@ -457,8 +457,20 @@ impl TypedRect { /// When casting from floating point to integer coordinates, the decimals are truncated /// as one would expect from a simple cast, but this behavior does not always make sense /// geometrically. Consider using round(), round_in or round_out() before casting. - pub fn cast(&self) -> Option> { - match (self.origin.cast(), self.size.cast()) { + pub fn cast(&self) -> TypedRect { + TypedRect::new( + self.origin.cast(), + self.size.cast(), + ) + } + + /// Fallible cast from one numeric representation to another, preserving the units. + /// + /// When casting from floating point to integer coordinates, the decimals are truncated + /// as one would expect from a simple cast, but this behavior does not always make sense + /// geometrically. Consider using round(), round_in or round_out() before casting. + pub fn try_cast(&self) -> Option> { + match (self.origin.try_cast(), self.size.try_cast()) { (Some(origin), Some(size)) => Some(TypedRect::new(origin, size)), _ => None, } @@ -505,12 +517,12 @@ impl + Sub, U> Typed impl TypedRect { /// Cast into an `f32` rectangle. pub fn to_f32(&self) -> TypedRect { - self.cast().unwrap() + self.cast() } /// Cast into an `f64` rectangle. pub fn to_f64(&self) -> TypedRect { - self.cast().unwrap() + self.cast() } /// Cast into an `usize` rectangle, truncating decimals if any. @@ -519,7 +531,7 @@ impl TypedRect { /// to `round()`, `round_in()` or `round_out()` before the cast in order to /// obtain the desired conversion behavior. pub fn to_usize(&self) -> TypedRect { - self.cast().unwrap() + self.cast() } /// Cast into an `u32` rectangle, truncating decimals if any. @@ -528,7 +540,7 @@ impl TypedRect { /// to `round()`, `round_in()` or `round_out()` before the cast in order to /// obtain the desired conversion behavior. pub fn to_u32(&self) -> TypedRect { - self.cast().unwrap() + self.cast() } /// Cast into an `i32` rectangle, truncating decimals if any. @@ -537,7 +549,7 @@ impl TypedRect { /// to `round()`, `round_in()` or `round_out()` before the cast in order to /// obtain the desired conversion behavior. pub fn to_i32(&self) -> TypedRect { - self.cast().unwrap() + self.cast() } /// Cast into an `i64` rectangle, truncating decimals if any. @@ -546,7 +558,7 @@ impl TypedRect { /// to `round()`, `round_in()` or `round_out()` before the cast in order to /// obtain the desired conversion behavior. pub fn to_i64(&self) -> TypedRect { - self.cast().unwrap() + self.cast() } } diff --git a/src/scale.rs b/src/scale.rs index d58c2ec2..44d940a8 100644 --- a/src/scale.rs +++ b/src/scale.rs @@ -123,7 +123,12 @@ impl, Src, Dst> Sub for TypedScale { impl TypedScale { /// Cast from one numeric representation to another, preserving the units. - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> TypedScale { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + pub fn try_cast(&self) -> Option> { NumCast::from(self.get()).map(TypedScale::new) } } diff --git a/src/size.rs b/src/size.rs index 0dd010b4..11aa0048 100644 --- a/src/size.rs +++ b/src/size.rs @@ -216,7 +216,16 @@ impl TypedSize2D { /// When casting from floating point to integer coordinates, the decimals are truncated /// as one would expect from a simple cast, but this behavior does not always make sense /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> TypedSize2D { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + /// + /// When casting from floating point to integer coordinates, the decimals are truncated + /// as one would expect from a simple cast, but this behavior does not always make sense + /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. + pub fn try_cast(&self) -> Option> { match (NumCast::from(self.width), NumCast::from(self.height)) { (Some(w), Some(h)) => Some(TypedSize2D::new(w, h)), _ => None, @@ -227,12 +236,12 @@ impl TypedSize2D { /// Cast into an `f32` size. pub fn to_f32(&self) -> TypedSize2D { - self.cast().unwrap() + self.cast() } /// Cast into an `f64` size. pub fn to_f64(&self) -> TypedSize2D { - self.cast().unwrap() + self.cast() } /// Cast into an `uint` size, truncating decimals if any. @@ -241,7 +250,7 @@ impl TypedSize2D { /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain /// the desired conversion behavior. pub fn to_usize(&self) -> TypedSize2D { - self.cast().unwrap() + self.cast() } /// Cast into an `u32` size, truncating decimals if any. @@ -250,7 +259,7 @@ impl TypedSize2D { /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain /// the desired conversion behavior. pub fn to_u32(&self) -> TypedSize2D { - self.cast().unwrap() + self.cast() } /// Cast into an `i32` size, truncating decimals if any. @@ -259,7 +268,7 @@ impl TypedSize2D { /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain /// the desired conversion behavior. pub fn to_i32(&self) -> TypedSize2D { - self.cast().unwrap() + self.cast() } /// Cast into an `i64` size, truncating decimals if any. @@ -268,7 +277,7 @@ impl TypedSize2D { /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain /// the desired conversion behavior. pub fn to_i64(&self) -> TypedSize2D { - self.cast().unwrap() + self.cast() } } diff --git a/src/transform2d.rs b/src/transform2d.rs index 9ac3c6ac..a2ebef8b 100644 --- a/src/transform2d.rs +++ b/src/transform2d.rs @@ -132,16 +132,23 @@ impl TypedTransform2D { impl TypedTransform2D { /// Cast from one numeric representation to another, preserving the units. - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> TypedTransform2D { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + pub fn try_cast(&self) -> Option> { match (NumCast::from(self.m11), NumCast::from(self.m12), NumCast::from(self.m21), NumCast::from(self.m22), NumCast::from(self.m31), NumCast::from(self.m32)) { (Some(m11), Some(m12), Some(m21), Some(m22), Some(m31), Some(m32)) => { - Some(TypedTransform2D::row_major(m11, m12, - m21, m22, - m31, m32)) + Some(TypedTransform2D::row_major( + m11, m12, + m21, m22, + m31, m32 + )) }, _ => None } diff --git a/src/transform3d.rs b/src/transform3d.rs index 495a10c3..619cf47c 100644 --- a/src/transform3d.rs +++ b/src/transform3d.rs @@ -688,7 +688,12 @@ impl TypedTransform3D { impl TypedTransform3D { /// Cast from one numeric representation to another, preserving the units. - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> TypedTransform3D { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + pub fn try_cast(&self) -> Option> { match (NumCast::from(self.m11), NumCast::from(self.m12), NumCast::from(self.m13), NumCast::from(self.m14), NumCast::from(self.m21), NumCast::from(self.m22), diff --git a/src/vector.rs b/src/vector.rs index f86bcb23..a0cccfac 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -335,7 +335,17 @@ impl TypedVector2D { /// as one would expect from a simple cast, but this behavior does not always make sense /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. #[inline] - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> TypedVector2D { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + /// + /// When casting from floating vector to integer coordinates, the decimals are truncated + /// as one would expect from a simple cast, but this behavior does not always make sense + /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. + #[inline] + pub fn try_cast(&self) -> Option> { match (NumCast::from(self.x), NumCast::from(self.y)) { (Some(x), Some(y)) => Some(TypedVector2D::new(x, y)), _ => None, @@ -347,13 +357,13 @@ impl TypedVector2D { /// Cast into an `f32` vector. #[inline] pub fn to_f32(&self) -> TypedVector2D { - self.cast().unwrap() + self.cast() } /// Cast into an `f64` vector. #[inline] pub fn to_f64(&self) -> TypedVector2D { - self.cast().unwrap() + self.cast() } /// Cast into an `usize` vector, truncating decimals if any. @@ -363,7 +373,7 @@ impl TypedVector2D { /// the desired conversion behavior. #[inline] pub fn to_usize(&self) -> TypedVector2D { - self.cast().unwrap() + self.cast() } /// Cast into an `u32` vector, truncating decimals if any. @@ -373,7 +383,7 @@ impl TypedVector2D { /// the desired conversion behavior. #[inline] pub fn to_u32(&self) -> TypedVector2D { - self.cast().unwrap() + self.cast() } /// Cast into an i32 vector, truncating decimals if any. @@ -383,7 +393,7 @@ impl TypedVector2D { /// the desired conversion behavior. #[inline] pub fn to_i32(&self) -> TypedVector2D { - self.cast().unwrap() + self.cast() } /// Cast into an i64 vector, truncating decimals if any. @@ -393,7 +403,7 @@ impl TypedVector2D { /// the desired conversion behavior. #[inline] pub fn to_i64(&self) -> TypedVector2D { - self.cast().unwrap() + self.cast() } } @@ -760,7 +770,17 @@ impl TypedVector3D { /// as one would expect from a simple cast, but this behavior does not always make sense /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. #[inline] - pub fn cast(&self) -> Option> { + pub fn cast(&self) -> TypedVector3D { + self.try_cast().unwrap() + } + + /// Fallible cast from one numeric representation to another, preserving the units. + /// + /// When casting from floating vector to integer coordinates, the decimals are truncated + /// as one would expect from a simple cast, but this behavior does not always make sense + /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting. + #[inline] + pub fn try_cast(&self) -> Option> { match ( NumCast::from(self.x), NumCast::from(self.y), @@ -776,13 +796,13 @@ impl TypedVector3D { /// Cast into an `f32` vector. #[inline] pub fn to_f32(&self) -> TypedVector3D { - self.cast().unwrap() + self.cast() } /// Cast into an `f64` vector. #[inline] pub fn to_f64(&self) -> TypedVector3D { - self.cast().unwrap() + self.cast() } /// Cast into an `usize` vector, truncating decimals if any. @@ -792,7 +812,7 @@ impl TypedVector3D { /// the desired conversion behavior. #[inline] pub fn to_usize(&self) -> TypedVector3D { - self.cast().unwrap() + self.cast() } /// Cast into an `u32` vector, truncating decimals if any. @@ -802,7 +822,7 @@ impl TypedVector3D { /// the desired conversion behavior. #[inline] pub fn to_u32(&self) -> TypedVector3D { - self.cast().unwrap() + self.cast() } /// Cast into an `i32` vector, truncating decimals if any. @@ -812,7 +832,7 @@ impl TypedVector3D { /// the desired conversion behavior. #[inline] pub fn to_i32(&self) -> TypedVector3D { - self.cast().unwrap() + self.cast() } /// Cast into an `i64` vector, truncating decimals if any. @@ -822,7 +842,7 @@ impl TypedVector3D { /// the desired conversion behavior. #[inline] pub fn to_i64(&self) -> TypedVector3D { - self.cast().unwrap() + self.cast() } }