Skip to content

Commit 766d2e9

Browse files
author
bors-servo
authored
Auto merge of #294 - nical:try-cst, r=kvark
Make cast infallible and add try_cast. Fixes #270. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/euclid/294) <!-- Reviewable:end -->
2 parents 54a98c0 + ee8d415 commit 766d2e9

File tree

8 files changed

+133
-51
lines changed

8 files changed

+133
-51
lines changed

src/length.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,12 @@ impl<U, T: Clone + Neg<Output = T>> Neg for Length<T, U> {
211211

212212
impl<Unit, T0: NumCast + Clone> Length<T0, Unit> {
213213
/// Cast from one numeric representation to another, preserving the units.
214-
pub fn cast<T1: NumCast + Clone>(&self) -> Option<Length<T1, Unit>> {
214+
pub fn cast<T1: NumCast + Clone>(&self) -> Length<T1, Unit> {
215+
self.try_cast().unwrap()
216+
}
217+
218+
/// Fallible cast from one numeric representation to another, preserving the units.
219+
pub fn try_cast<T1: NumCast + Clone>(&self) -> Option<Length<T1, Unit>> {
215220
NumCast::from(self.get()).map(Length::new)
216221
}
217222
}
@@ -461,7 +466,7 @@ mod tests {
461466
fn test_cast() {
462467
let length_as_i32: Length<i32, Cm> = Length::new(5);
463468

464-
let result: Length<f32, Cm> = length_as_i32.cast().unwrap();
469+
let result: Length<f32, Cm> = length_as_i32.cast();
465470

466471
let length_as_f32: Length<f32, Cm> = Length::new(5.0);
467472
assert_eq!(result, length_as_f32);

src/point.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,16 @@ impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
286286
/// as one would expect from a simple cast, but this behavior does not always make sense
287287
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
288288
#[inline]
289-
pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint2D<NewT, U>> {
289+
pub fn cast<NewT: NumCast + Copy>(&self) -> TypedPoint2D<NewT, U> {
290+
self.try_cast().unwrap()
291+
}
292+
293+
/// Fallible cast from one numeric representation to another, preserving the units.
294+
///
295+
/// When casting from floating point to integer coordinates, the decimals are truncated
296+
/// as one would expect from a simple cast, but this behavior does not always make sense
297+
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
298+
pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint2D<NewT, U>> {
290299
match (NumCast::from(self.x), NumCast::from(self.y)) {
291300
(Some(x), Some(y)) => Some(point2(x, y)),
292301
_ => None,
@@ -298,13 +307,13 @@ impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
298307
/// Cast into an `f32` point.
299308
#[inline]
300309
pub fn to_f32(&self) -> TypedPoint2D<f32, U> {
301-
self.cast().unwrap()
310+
self.cast()
302311
}
303312

304313
/// Cast into an `f64` point.
305314
#[inline]
306315
pub fn to_f64(&self) -> TypedPoint2D<f64, U> {
307-
self.cast().unwrap()
316+
self.cast()
308317
}
309318

310319
/// Cast into an `usize` point, truncating decimals if any.
@@ -314,7 +323,7 @@ impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
314323
/// the desired conversion behavior.
315324
#[inline]
316325
pub fn to_usize(&self) -> TypedPoint2D<usize, U> {
317-
self.cast().unwrap()
326+
self.cast()
318327
}
319328

320329
/// Cast into an `u32` point, truncating decimals if any.
@@ -324,7 +333,7 @@ impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
324333
/// the desired conversion behavior.
325334
#[inline]
326335
pub fn to_u32(&self) -> TypedPoint2D<u32, U> {
327-
self.cast().unwrap()
336+
self.cast()
328337
}
329338

330339
/// Cast into an i32 point, truncating decimals if any.
@@ -334,7 +343,7 @@ impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
334343
/// the desired conversion behavior.
335344
#[inline]
336345
pub fn to_i32(&self) -> TypedPoint2D<i32, U> {
337-
self.cast().unwrap()
346+
self.cast()
338347
}
339348

340349
/// Cast into an i64 point, truncating decimals if any.
@@ -344,7 +353,7 @@ impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
344353
/// the desired conversion behavior.
345354
#[inline]
346355
pub fn to_i64(&self) -> TypedPoint2D<i64, U> {
347-
self.cast().unwrap()
356+
self.cast()
348357
}
349358
}
350359

@@ -650,7 +659,17 @@ impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
650659
/// as one would expect from a simple cast, but this behavior does not always make sense
651660
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
652661
#[inline]
653-
pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint3D<NewT, U>> {
662+
pub fn cast<NewT: NumCast + Copy>(&self) -> TypedPoint3D<NewT, U> {
663+
self.try_cast().unwrap()
664+
}
665+
666+
/// Fallible cast from one numeric representation to another, preserving the units.
667+
///
668+
/// When casting from floating point to integer coordinates, the decimals are truncated
669+
/// as one would expect from a simple cast, but this behavior does not always make sense
670+
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
671+
#[inline]
672+
pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint3D<NewT, U>> {
654673
match (
655674
NumCast::from(self.x),
656675
NumCast::from(self.y),
@@ -666,13 +685,13 @@ impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
666685
/// Cast into an `f32` point.
667686
#[inline]
668687
pub fn to_f32(&self) -> TypedPoint3D<f32, U> {
669-
self.cast().unwrap()
688+
self.cast()
670689
}
671690

672691
/// Cast into an `f64` point.
673692
#[inline]
674693
pub fn to_f64(&self) -> TypedPoint3D<f64, U> {
675-
self.cast().unwrap()
694+
self.cast()
676695
}
677696

678697
/// Cast into an `usize` point, truncating decimals if any.
@@ -682,7 +701,7 @@ impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
682701
/// the desired conversion behavior.
683702
#[inline]
684703
pub fn to_usize(&self) -> TypedPoint3D<usize, U> {
685-
self.cast().unwrap()
704+
self.cast()
686705
}
687706

688707
/// Cast into an `u32` point, truncating decimals if any.
@@ -692,7 +711,7 @@ impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
692711
/// the desired conversion behavior.
693712
#[inline]
694713
pub fn to_u32(&self) -> TypedPoint3D<u32, U> {
695-
self.cast().unwrap()
714+
self.cast()
696715
}
697716

698717
/// Cast into an `i32` point, truncating decimals if any.
@@ -702,7 +721,7 @@ impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
702721
/// the desired conversion behavior.
703722
#[inline]
704723
pub fn to_i32(&self) -> TypedPoint3D<i32, U> {
705-
self.cast().unwrap()
724+
self.cast()
706725
}
707726

708727
/// Cast into an `i64` point, truncating decimals if any.
@@ -712,7 +731,7 @@ impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
712731
/// the desired conversion behavior.
713732
#[inline]
714733
pub fn to_i64(&self) -> TypedPoint3D<i64, U> {
715-
self.cast().unwrap()
734+
self.cast()
716735
}
717736
}
718737

src/rect.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,20 @@ impl<T0: NumCast + Copy, Unit> TypedRect<T0, Unit> {
470470
/// When casting from floating point to integer coordinates, the decimals are truncated
471471
/// as one would expect from a simple cast, but this behavior does not always make sense
472472
/// geometrically. Consider using round(), round_in or round_out() before casting.
473-
pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedRect<T1, Unit>> {
474-
match (self.origin.cast(), self.size.cast()) {
473+
pub fn cast<T1: NumCast + Copy>(&self) -> TypedRect<T1, Unit> {
474+
TypedRect::new(
475+
self.origin.cast(),
476+
self.size.cast(),
477+
)
478+
}
479+
480+
/// Fallible cast from one numeric representation to another, preserving the units.
481+
///
482+
/// When casting from floating point to integer coordinates, the decimals are truncated
483+
/// as one would expect from a simple cast, but this behavior does not always make sense
484+
/// geometrically. Consider using round(), round_in or round_out() before casting.
485+
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<TypedRect<T1, Unit>> {
486+
match (self.origin.try_cast(), self.size.try_cast()) {
475487
(Some(origin), Some(size)) => Some(TypedRect::new(origin, size)),
476488
_ => None,
477489
}
@@ -518,12 +530,12 @@ impl<T: Floor + Ceil + Round + Add<T, Output = T> + Sub<T, Output = T>, U> Typed
518530
impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
519531
/// Cast into an `f32` rectangle.
520532
pub fn to_f32(&self) -> TypedRect<f32, Unit> {
521-
self.cast().unwrap()
533+
self.cast()
522534
}
523535

524536
/// Cast into an `f64` rectangle.
525537
pub fn to_f64(&self) -> TypedRect<f64, Unit> {
526-
self.cast().unwrap()
538+
self.cast()
527539
}
528540

529541
/// Cast into an `usize` rectangle, truncating decimals if any.
@@ -532,7 +544,7 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
532544
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
533545
/// obtain the desired conversion behavior.
534546
pub fn to_usize(&self) -> TypedRect<usize, Unit> {
535-
self.cast().unwrap()
547+
self.cast()
536548
}
537549

538550
/// Cast into an `u32` rectangle, truncating decimals if any.
@@ -541,7 +553,7 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
541553
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
542554
/// obtain the desired conversion behavior.
543555
pub fn to_u32(&self) -> TypedRect<u32, Unit> {
544-
self.cast().unwrap()
556+
self.cast()
545557
}
546558

547559
/// Cast into an `i32` rectangle, truncating decimals if any.
@@ -550,7 +562,7 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
550562
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
551563
/// obtain the desired conversion behavior.
552564
pub fn to_i32(&self) -> TypedRect<i32, Unit> {
553-
self.cast().unwrap()
565+
self.cast()
554566
}
555567

556568
/// Cast into an `i64` rectangle, truncating decimals if any.
@@ -559,7 +571,7 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
559571
/// to `round()`, `round_in()` or `round_out()` before the cast in order to
560572
/// obtain the desired conversion behavior.
561573
pub fn to_i64(&self) -> TypedRect<i64, Unit> {
562-
self.cast().unwrap()
574+
self.cast()
563575
}
564576
}
565577

src/scale.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,12 @@ impl<T: Clone + Sub<T, Output = T>, Src, Dst> Sub for TypedScale<T, Src, Dst> {
123123

124124
impl<T: NumCast + Clone, Src, Dst0> TypedScale<T, Src, Dst0> {
125125
/// Cast from one numeric representation to another, preserving the units.
126-
pub fn cast<T1: NumCast + Clone>(&self) -> Option<TypedScale<T1, Src, Dst0>> {
126+
pub fn cast<T1: NumCast + Clone>(&self) -> TypedScale<T1, Src, Dst0> {
127+
self.try_cast().unwrap()
128+
}
129+
130+
/// Fallible cast from one numeric representation to another, preserving the units.
131+
pub fn try_cast<T1: NumCast + Clone>(&self) -> Option<TypedScale<T1, Src, Dst0>> {
127132
NumCast::from(self.get()).map(TypedScale::new)
128133
}
129134
}

src/size.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,16 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
216216
/// When casting from floating point to integer coordinates, the decimals are truncated
217217
/// as one would expect from a simple cast, but this behavior does not always make sense
218218
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
219-
pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedSize2D<NewT, Unit>> {
219+
pub fn cast<NewT: NumCast + Copy>(&self) -> TypedSize2D<NewT, Unit> {
220+
self.try_cast().unwrap()
221+
}
222+
223+
/// Fallible cast from one numeric representation to another, preserving the units.
224+
///
225+
/// When casting from floating point to integer coordinates, the decimals are truncated
226+
/// as one would expect from a simple cast, but this behavior does not always make sense
227+
/// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
228+
pub fn try_cast<NewT: NumCast + Copy>(&self) -> Option<TypedSize2D<NewT, Unit>> {
220229
match (NumCast::from(self.width), NumCast::from(self.height)) {
221230
(Some(w), Some(h)) => Some(TypedSize2D::new(w, h)),
222231
_ => None,
@@ -227,12 +236,12 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
227236

228237
/// Cast into an `f32` size.
229238
pub fn to_f32(&self) -> TypedSize2D<f32, Unit> {
230-
self.cast().unwrap()
239+
self.cast()
231240
}
232241

233242
/// Cast into an `f64` size.
234243
pub fn to_f64(&self) -> TypedSize2D<f64, Unit> {
235-
self.cast().unwrap()
244+
self.cast()
236245
}
237246

238247
/// Cast into an `uint` size, truncating decimals if any.
@@ -241,7 +250,7 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
241250
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
242251
/// the desired conversion behavior.
243252
pub fn to_usize(&self) -> TypedSize2D<usize, Unit> {
244-
self.cast().unwrap()
253+
self.cast()
245254
}
246255

247256
/// Cast into an `u32` size, truncating decimals if any.
@@ -250,7 +259,7 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
250259
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
251260
/// the desired conversion behavior.
252261
pub fn to_u32(&self) -> TypedSize2D<u32, Unit> {
253-
self.cast().unwrap()
262+
self.cast()
254263
}
255264

256265
/// Cast into an `i32` size, truncating decimals if any.
@@ -259,7 +268,7 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
259268
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
260269
/// the desired conversion behavior.
261270
pub fn to_i32(&self) -> TypedSize2D<i32, Unit> {
262-
self.cast().unwrap()
271+
self.cast()
263272
}
264273

265274
/// Cast into an `i64` size, truncating decimals if any.
@@ -268,7 +277,7 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
268277
/// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
269278
/// the desired conversion behavior.
270279
pub fn to_i64(&self) -> TypedSize2D<i64, Unit> {
271-
self.cast().unwrap()
280+
self.cast()
272281
}
273282
}
274283

src/transform2d.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,23 @@ impl<T: Copy, Src, Dst> TypedTransform2D<T, Src, Dst> {
134134

135135
impl<T0: NumCast + Copy, Src, Dst> TypedTransform2D<T0, Src, Dst> {
136136
/// Cast from one numeric representation to another, preserving the units.
137-
pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform2D<T1, Src, Dst>> {
137+
pub fn cast<T1: NumCast + Copy>(&self) -> TypedTransform2D<T1, Src, Dst> {
138+
self.try_cast().unwrap()
139+
}
140+
141+
/// Fallible cast from one numeric representation to another, preserving the units.
142+
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform2D<T1, Src, Dst>> {
138143
match (NumCast::from(self.m11), NumCast::from(self.m12),
139144
NumCast::from(self.m21), NumCast::from(self.m22),
140145
NumCast::from(self.m31), NumCast::from(self.m32)) {
141146
(Some(m11), Some(m12),
142147
Some(m21), Some(m22),
143148
Some(m31), Some(m32)) => {
144-
Some(TypedTransform2D::row_major(m11, m12,
145-
m21, m22,
146-
m31, m32))
149+
Some(TypedTransform2D::row_major(
150+
m11, m12,
151+
m21, m22,
152+
m31, m32
153+
))
147154
},
148155
_ => None
149156
}

src/transform3d.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,12 @@ impl<T: Copy, Src, Dst> TypedTransform3D<T, Src, Dst> {
692692

693693
impl<T0: NumCast + Copy, Src, Dst> TypedTransform3D<T0, Src, Dst> {
694694
/// Cast from one numeric representation to another, preserving the units.
695-
pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform3D<T1, Src, Dst>> {
695+
pub fn cast<T1: NumCast + Copy>(&self) -> TypedTransform3D<T1, Src, Dst> {
696+
self.try_cast().unwrap()
697+
}
698+
699+
/// Fallible cast from one numeric representation to another, preserving the units.
700+
pub fn try_cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform3D<T1, Src, Dst>> {
696701
match (NumCast::from(self.m11), NumCast::from(self.m12),
697702
NumCast::from(self.m13), NumCast::from(self.m14),
698703
NumCast::from(self.m21), NumCast::from(self.m22),

0 commit comments

Comments
 (0)