servo: Merge #14261 - Prefer Either type for LengthOrNumber (from Wafflespeanut:lon); r=SimonSapin
authorRavi Shankar <wafflespeanut@gmail.com>
Fri, 18 Nov 2016 22:20:04 -0600
changeset 340175 8d06eca5a3e3007bed97c6df478531fa18f322a3
parent 340174 cbfe4c2e864d60e1ff3d9a75599038dacb9ab6c7
child 340176 9d91cefb5476e1da0840406029ce219d3d99aef1
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersSimonSapin
servo: Merge #14261 - Prefer Either type for LengthOrNumber (from Wafflespeanut:lon); r=SimonSapin <!-- Please describe your changes on the following line: --> This adds `impl GeckoStyleCoordConvertible for Either<A, B>` and makes `LengthOrNumber` prefer `Either<A, B>`. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach build-geckolib` does not report any errors - [x] `./mach test-tidy` does not report any errors <!-- Either: --> - [x] These changes do not require tests because it's a refactor <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> r? @SimonSapin Source-Repo: https://github.com/servo/servo Source-Revision: 0c55d461f1d6ab29f8309c81ccb8e4fca3461929
servo/components/style/gecko/values.rs
servo/components/style/properties/longhand/border.mako.rs
servo/components/style/values/computed/length.rs
servo/components/style/values/specified/length.rs
--- a/servo/components/style/gecko/values.rs
+++ b/servo/components/style/gecko/values.rs
@@ -5,37 +5,65 @@
 #![allow(unsafe_code)]
 
 use app_units::Au;
 use cssparser::RGBA;
 use gecko_bindings::structs::{NS_RADIUS_CLOSEST_SIDE, NS_RADIUS_FARTHEST_SIDE};
 use gecko_bindings::structs::nsStyleCoord;
 use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
 use std::cmp::max;
-use values::computed::{LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
-use values::computed::{LengthOrPercentageOrNone, Angle};
+use values::Either;
+use values::computed::{Angle, LengthOrPercentageOrNone, Number};
+use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
 use values::computed::basic_shape::ShapeRadius;
 
 pub trait StyleCoordHelpers {
     fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T);
 }
 
 impl StyleCoordHelpers for nsStyleCoord {
     #[inline]
     fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T) {
         val.to_gecko_style_coord(self);
     }
 }
 
-
 pub trait GeckoStyleCoordConvertible : Sized {
     fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T);
     fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self>;
 }
 
+impl<A: GeckoStyleCoordConvertible, B: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Either<A, B> {
+    fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
+        match *self {
+            Either::First(ref v) => v.to_gecko_style_coord(coord),
+            Either::Second(ref v) => v.to_gecko_style_coord(coord),
+        }
+    }
+
+    fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
+        A::from_gecko_style_coord(coord)
+          .map(Either::First)
+          .or_else(|| B::from_gecko_style_coord(coord).map(Either::Second))
+    }
+}
+
+impl GeckoStyleCoordConvertible for Number {
+    fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
+        coord.set_value(CoordDataValue::Factor(*self));
+    }
+
+    fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
+        match coord.as_value() {
+            CoordDataValue::Factor(f) => Some(f),
+            _ => None,
+        }
+    }
+}
+
 impl GeckoStyleCoordConvertible for LengthOrPercentage {
     fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
         let value = match *self {
             LengthOrPercentage::Length(au) => CoordDataValue::Coord(au.0),
             LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p),
             LengthOrPercentage::Calc(calc) => CoordDataValue::Calc(calc.into()),
         };
         coord.set_value(value);
@@ -103,34 +131,16 @@ impl GeckoStyleCoordConvertible for Leng
             CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)),
             CoordDataValue::None => Some(LengthOrPercentageOrNone::None),
             CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
             _ => None,
         }
     }
 }
 
-impl GeckoStyleCoordConvertible for LengthOrNumber {
-    fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
-        let value = match *self {
-            LengthOrNumber::Length(au) => CoordDataValue::Coord(au.0),
-            LengthOrNumber::Number(number) => CoordDataValue::Factor(number),
-        };
-        coord.set_value(value);
-    }
-
-    fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
-        match coord.as_value() {
-            CoordDataValue::Coord(coord) => Some(LengthOrNumber::Length(Au(coord))),
-            CoordDataValue::Factor(f) => Some(LengthOrNumber::Number(f)),
-            _ => None,
-        }
-    }
-}
-
 impl GeckoStyleCoordConvertible for ShapeRadius {
     fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
         match *self {
             ShapeRadius::ClosestSide => {
                 coord.set_value(CoordDataValue::Enumerated(NS_RADIUS_CLOSEST_SIDE))
             }
             ShapeRadius::FarthestSide => {
                 coord.set_value(CoordDataValue::Enumerated(NS_RADIUS_FARTHEST_SIDE))
--- a/servo/components/style/properties/longhand/border.mako.rs
+++ b/servo/components/style/properties/longhand/border.mako.rs
@@ -190,25 +190,23 @@
                 try!(value.to_css(dest));
             }
             Ok(())
         }
     }
 
     #[inline]
     pub fn get_initial_value() -> computed_value::T {
-        computed_value::T(computed::LengthOrNumber::Number(0.0),
-                          computed::LengthOrNumber::Number(0.0),
-                          computed::LengthOrNumber::Number(0.0),
-                          computed::LengthOrNumber::Number(0.0))
+        computed_value::T(Either::Second(0.0), Either::Second(0.0),
+                          Either::Second(0.0), Either::Second(0.0))
     }
 
     #[inline]
     pub fn get_initial_specified_value() -> SpecifiedValue {
-        SpecifiedValue(vec![LengthOrNumber::Number(Number(0.0))])
+        SpecifiedValue(vec![Either::Second(Number(0.0))])
     }
 
     impl ToComputedValue for SpecifiedValue {
         type ComputedValue = computed_value::T;
 
         #[inline]
         fn to_computed_value(&self, context: &Context) -> computed_value::T {
             let length = self.0.len();
--- a/servo/components/style/values/computed/length.rs
+++ b/servo/components/style/values/computed/length.rs
@@ -466,57 +466,11 @@ impl ToCss for LengthOrPercentageOrNone 
             LengthOrPercentageOrNone::Calc(calc) => calc.to_css(dest),
             LengthOrPercentageOrNone::None => dest.write_str("none"),
         }
     }
 }
 
 pub type LengthOrNone = Either<Length, None_>;
 
-#[derive(Clone, PartialEq)]
-#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-pub enum LengthOrNumber {
-    Length(Length),
-    Number(Number),
-}
-
-impl fmt::Debug for LengthOrNumber {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            LengthOrNumber::Length(length) => write!(f, "{:?}", length),
-            LengthOrNumber::Number(number) => write!(f, "{:?}", number),
-        }
-    }
-}
-
-impl ToComputedValue for specified::LengthOrNumber {
-    type ComputedValue = LengthOrNumber;
-
-    #[inline]
-    fn to_computed_value(&self, context: &Context) -> LengthOrNumber {
-        match *self {
-            specified::LengthOrNumber::Length(len) =>
-                LengthOrNumber::Length(len.to_computed_value(context)),
-            specified::LengthOrNumber::Number(number) =>
-                LengthOrNumber::Number(number.to_computed_value(context)),
-        }
-    }
-    #[inline]
-    fn from_computed_value(computed: &LengthOrNumber) -> Self {
-        match *computed {
-            LengthOrNumber::Length(len) =>
-                specified::LengthOrNumber::Length(ToComputedValue::from_computed_value(&len)),
-            LengthOrNumber::Number(number) =>
-                specified::LengthOrNumber::Number(ToComputedValue::from_computed_value(&number)),
-        }
-    }
-}
-
-impl ToCss for LengthOrNumber {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-        match *self {
-            LengthOrNumber::Length(len) => len.to_css(dest),
-            LengthOrNumber::Number(number) => number.to_css(dest),
-        }
-    }
-}
+pub type LengthOrNumber = Either<Length, Number>;
 
 pub type Length = Au;
--- a/servo/components/style/values/specified/length.rs
+++ b/servo/components/style/values/specified/length.rs
@@ -1003,45 +1003,9 @@ impl Parse for LengthOrPercentageOrAutoO
                 let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
                 Ok(LengthOrPercentageOrAutoOrContent::Calc(calc))
             },
             _ => Err(())
         }
     }
 }
 
-#[derive(Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-pub enum LengthOrNumber {
-    Length(Length),
-    Number(Number),
-}
-
-impl HasViewportPercentage for LengthOrNumber {
-    fn has_viewport_percentage(&self) -> bool {
-        match *self {
-            LengthOrNumber::Length(length) => length.has_viewport_percentage(),
-            _ => false
-        }
-    }
-}
-
-impl ToCss for LengthOrNumber {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-        match *self {
-            LengthOrNumber::Length(len) => len.to_css(dest),
-            LengthOrNumber::Number(number) => number.to_css(dest),
-        }
-    }
-}
-
-impl Parse for LengthOrNumber {
-    fn parse(input: &mut Parser) -> Result<Self, ()> {
-        let length = input.try(Length::parse);
-        if let Ok(len) = length {
-            return Ok(LengthOrNumber::Length(len));
-        }
-
-        let num = try!(Number::parse_non_negative(input));
-        Ok(LengthOrNumber::Number(num))
-    }
-}
-
+pub type LengthOrNumber = Either<Length, Number>;