Skip to main content

style/values/computed/
percentage.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Computed percentages.
6
7use crate::derives::*;
8use crate::values::generics::{ClampToNonNegative, NonNegative};
9use crate::values::specified::percentage::ToPercentage;
10use crate::values::{reify_percentage, serialize_normalized_percentage, CSSFloat};
11use crate::Zero;
12use std::fmt;
13use style_traits::{CssWriter, ToCss, ToTyped, TypedValue};
14
15/// A computed percentage.
16#[derive(
17    Animate,
18    Clone,
19    ComputeSquaredDistance,
20    Copy,
21    Debug,
22    Default,
23    Deserialize,
24    MallocSizeOf,
25    PartialEq,
26    PartialOrd,
27    Serialize,
28    SpecifiedValueInfo,
29    ToAnimatedValue,
30    ToAnimatedZero,
31    ToComputedValue,
32    ToResolvedValue,
33    ToShmem,
34)]
35#[repr(C)]
36pub struct Percentage(pub CSSFloat);
37
38impl ClampToNonNegative for Percentage {
39    #[inline]
40    fn clamp_to_non_negative(self) -> Self {
41        Percentage(self.0.max(0.))
42    }
43}
44
45impl Percentage {
46    /// 100%
47    #[inline]
48    pub fn hundred() -> Self {
49        Percentage(1.)
50    }
51
52    /// Returns the absolute value for this percentage.
53    #[inline]
54    pub fn abs(&self) -> Self {
55        Percentage(self.0.abs())
56    }
57}
58
59impl Zero for Percentage {
60    fn zero() -> Self {
61        Percentage(0.)
62    }
63
64    fn is_zero(&self) -> bool {
65        self.0 == 0.
66    }
67}
68
69impl ToPercentage for Percentage {
70    fn to_percentage(&self) -> CSSFloat {
71        self.0
72    }
73}
74
75impl std::ops::AddAssign for Percentage {
76    fn add_assign(&mut self, other: Self) {
77        self.0 += other.0
78    }
79}
80
81impl std::ops::Add for Percentage {
82    type Output = Self;
83
84    fn add(self, other: Self) -> Self {
85        Percentage(self.0 + other.0)
86    }
87}
88
89impl std::ops::Sub for Percentage {
90    type Output = Self;
91
92    fn sub(self, other: Self) -> Self {
93        Percentage(self.0 - other.0)
94    }
95}
96
97impl std::ops::Rem for Percentage {
98    type Output = Self;
99
100    fn rem(self, other: Self) -> Self {
101        Percentage(self.0 % other.0)
102    }
103}
104
105impl ToCss for Percentage {
106    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
107    where
108        W: fmt::Write,
109    {
110        serialize_normalized_percentage(self.0, dest)
111    }
112}
113
114impl ToTyped for Percentage {
115    fn to_typed(&self) -> Option<TypedValue> {
116        Some(TypedValue::Numeric(reify_percentage(self.0)))
117    }
118}
119
120/// A wrapper over a `Percentage`, whose value should be clamped to 0.
121pub type NonNegativePercentage = NonNegative<Percentage>;
122
123impl NonNegativePercentage {
124    /// 100%
125    #[inline]
126    pub fn hundred() -> Self {
127        NonNegative(Percentage::hundred())
128    }
129}