Auto merge of #14261 - Wafflespeanut:lon, r=SimonSapin

Prefer Either type for LengthOrNumber

<!-- 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

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14261)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-11-18 22:20:04 -06:00 committed by GitHub
commit 0c55d461f1
4 changed files with 36 additions and 110 deletions

View file

@ -10,8 +10,9 @@ 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 {
@ -25,12 +26,39 @@ impl StyleCoordHelpers for nsStyleCoord {
}
}
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 {
@ -108,24 +136,6 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
}
}
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 {

View file

@ -195,15 +195,13 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
#[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 {

View file

@ -471,52 +471,6 @@ impl ToCss for LengthOrPercentageOrNone {
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;

View file

@ -1008,40 +1008,4 @@ impl Parse for LengthOrPercentageOrAutoOrContent {
}
}
#[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>;