Make nsStyleUnion sugar use traits

This commit is contained in:
Manish Goregaokar 2016-07-20 19:08:31 +05:30
parent 6e9a68a0db
commit 73d7db0d5e
No known key found for this signature in database
GPG key ID: 3BBF4D3E2EF79F98
4 changed files with 326 additions and 241 deletions

View file

@ -7,120 +7,114 @@
use app_units::Au;
use cssparser::RGBA;
use gecko_bindings::structs::nsStyleCoord;
use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataValues};
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use std::cmp::max;
use values::computed::Angle;
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
pub trait StyleCoordHelpers {
fn copy_from(&mut self, other: &Self);
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T);
}
impl StyleCoordHelpers for nsStyleCoord {
#[inline]
fn copy_from(&mut self, other: &Self) {
self.data().copy_from(&other.data())
}
#[inline]
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T) {
val.to_gecko_style_coord(&mut self.data());
val.to_gecko_style_coord(self);
}
}
pub trait GeckoStyleCoordConvertible : Sized {
fn to_gecko_style_coord(&self, coord: &mut CoordData);
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self>;
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T);
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self>;
}
impl GeckoStyleCoordConvertible for LengthOrPercentage {
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
LengthOrPercentage::Length(au) => CoordDataValues::Coord(au.0),
LengthOrPercentage::Percentage(p) => CoordDataValues::Percent(p),
LengthOrPercentage::Calc(calc) => CoordDataValues::Calc(calc.into()),
LengthOrPercentage::Length(au) => CoordDataValue::Coord(au.0),
LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p),
LengthOrPercentage::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
coord.set_enum(value);
coord.set_value(value);
}
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
match coord.as_enum() {
CoordDataValues::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord))),
CoordDataValues::Percent(p) => Some(LengthOrPercentage::Percentage(p)),
CoordDataValues::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())),
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord))),
CoordDataValue::Percent(p) => Some(LengthOrPercentage::Percentage(p)),
CoordDataValue::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())),
_ => None,
}
}
}
impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
LengthOrPercentageOrAuto::Length(au) => CoordDataValues::Coord(au.0),
LengthOrPercentageOrAuto::Percentage(p) => CoordDataValues::Percent(p),
LengthOrPercentageOrAuto::Auto => CoordDataValues::Auto,
LengthOrPercentageOrAuto::Calc(calc) => CoordDataValues::Calc(calc.into()),
LengthOrPercentageOrAuto::Length(au) => CoordDataValue::Coord(au.0),
LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p),
LengthOrPercentageOrAuto::Auto => CoordDataValue::Auto,
LengthOrPercentageOrAuto::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
coord.set_enum(value);
coord.set_value(value);
}
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
match coord.as_enum() {
CoordDataValues::Coord(coord) => Some(LengthOrPercentageOrAuto::Length(Au(coord))),
CoordDataValues::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(p)),
CoordDataValues::Auto => Some(LengthOrPercentageOrAuto::Auto),
CoordDataValues::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())),
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrAuto::Length(Au(coord))),
CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(p)),
CoordDataValue::Auto => Some(LengthOrPercentageOrAuto::Auto),
CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())),
_ => None,
}
}
}
impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
LengthOrPercentageOrNone::Length(au) => CoordDataValues::Coord(au.0),
LengthOrPercentageOrNone::Percentage(p) => CoordDataValues::Percent(p),
LengthOrPercentageOrNone::None => CoordDataValues::None,
LengthOrPercentageOrNone::Calc(calc) => CoordDataValues::Calc(calc.into()),
LengthOrPercentageOrNone::Length(au) => CoordDataValue::Coord(au.0),
LengthOrPercentageOrNone::Percentage(p) => CoordDataValue::Percent(p),
LengthOrPercentageOrNone::None => CoordDataValue::None,
LengthOrPercentageOrNone::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
coord.set_enum(value);
coord.set_value(value);
}
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
match coord.as_enum() {
CoordDataValues::Coord(coord) => Some(LengthOrPercentageOrNone::Length(Au(coord))),
CoordDataValues::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)),
CoordDataValues::None => Some(LengthOrPercentageOrNone::None),
CoordDataValues::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrNone::Length(Au(coord))),
CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)),
CoordDataValue::None => Some(LengthOrPercentageOrNone::None),
CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
_ => None,
}
}
}
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) {
if let Some(ref me) = *self {
me.to_gecko_style_coord(coord);
} else {
coord.set_enum(CoordDataValues::None);
coord.set_value(CoordDataValue::None);
}
}
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
fn from_gecko_style_coord<U: CoordData>(coord: &U) -> Option<Self> {
Some(T::from_gecko_style_coord(coord))
}
}
impl GeckoStyleCoordConvertible for Angle {
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
coord.set_enum(CoordDataValues::Radian(self.radians()))
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
coord.set_value(CoordDataValue::Radian(self.radians()))
}
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
if let CoordDataValues::Radian(r) = coord.as_enum() {
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
if let CoordDataValue::Radian(r) = coord.as_value() {
Some(Angle::from_radians(r))
// XXXManishearth should this handle Degree too?
} else {