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