mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Add an Either<A, B> type for sharing specified and computed CSS types
This commit is contained in:
parent
32a953f0ba
commit
f36a573d2d
1 changed files with 69 additions and 1 deletions
|
@ -6,7 +6,11 @@
|
|||
//!
|
||||
//! [values]: https://drafts.csswg.org/css-values/
|
||||
|
||||
pub use cssparser::RGBA;
|
||||
pub use cssparser::{RGBA, Parser};
|
||||
|
||||
use parser::Parse;
|
||||
use std::fmt::{self, Debug};
|
||||
use style_traits::ToCss;
|
||||
|
||||
macro_rules! define_numbered_css_keyword_enum {
|
||||
($name: ident: $( $css: expr => $variant: ident = $value: expr ),+,) => {
|
||||
|
@ -59,3 +63,67 @@ impl<T> HasViewportPercentage for T where T: NoViewportPercentage {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Copy)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum Either<A, B> {
|
||||
First(A),
|
||||
Second(B),
|
||||
}
|
||||
|
||||
impl<A: Debug, B: Debug> Debug for Either<A, B> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Either::First(ref v) => v.fmt(f),
|
||||
Either::Second(ref v) => v.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: ToCss, B: ToCss> ToCss for Either<A, B> {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
Either::First(ref v) => v.to_css(dest),
|
||||
Either::Second(ref v) => v.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HasViewportPercentage, B: HasViewportPercentage> HasViewportPercentage for Either<A, B> {
|
||||
fn has_viewport_percentage(&self) -> bool {
|
||||
match *self {
|
||||
Either::First(ref v) => v.has_viewport_percentage(),
|
||||
Either::Second(ref v) => v.has_viewport_percentage(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Parse, B: Parse> Parse for Either<A, B> {
|
||||
fn parse(input: &mut Parser) -> Result<Either<A, B>, ()> {
|
||||
if let Ok(v) = input.try(|i| A::parse(i)) {
|
||||
Ok(Either::First(v))
|
||||
} else {
|
||||
B::parse(input).map(Either::Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use self::computed::{Context, ToComputedValue};
|
||||
|
||||
impl<A: ToComputedValue, B: ToComputedValue> ToComputedValue for Either<A, B> {
|
||||
type ComputedValue = Either<A::ComputedValue, B::ComputedValue>;
|
||||
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
Either::First(ref a) => Either::First(a.to_computed_value(context)),
|
||||
Either::Second(ref a) => Either::Second(a.to_computed_value(context)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
match *computed {
|
||||
Either::First(ref a) => Either::First(ToComputedValue::from_computed_value(a)),
|
||||
Either::Second(ref a) => Either::Second(ToComputedValue::from_computed_value(a)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue