style/values/generics/
mod.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//! Generic types that share their serialization implementations
6//! for both specified and computed values.
7
8use crate::Zero;
9use std::ops::Add;
10
11pub mod animation;
12pub mod background;
13pub mod basic_shape;
14pub mod border;
15#[path = "box.rs"]
16pub mod box_;
17pub mod calc;
18pub mod color;
19pub mod column;
20pub mod counters;
21pub mod easing;
22pub mod effects;
23pub mod flex;
24pub mod font;
25pub mod grid;
26pub mod image;
27pub mod length;
28pub mod motion;
29pub mod page;
30pub mod position;
31pub mod ratio;
32pub mod rect;
33pub mod size;
34pub mod svg;
35pub mod text;
36pub mod transform;
37pub mod ui;
38pub mod url;
39
40/// A wrapper of Non-negative values.
41#[derive(
42    Animate,
43    Clone,
44    ComputeSquaredDistance,
45    Copy,
46    Debug,
47    Deserialize,
48    Hash,
49    MallocSizeOf,
50    PartialEq,
51    PartialOrd,
52    SpecifiedValueInfo,
53    Serialize,
54    ToAnimatedZero,
55    ToComputedValue,
56    ToCss,
57    ToResolvedValue,
58    ToShmem,
59    ToTyped,
60)]
61#[repr(transparent)]
62pub struct NonNegative<T>(pub T);
63
64/// A trait to clamp a negative value to another.
65pub trait ClampToNonNegative {
66    /// Clamps the value to be non-negative after an animation.
67    fn clamp_to_non_negative(self) -> Self;
68}
69
70impl ClampToNonNegative for f32 {
71    fn clamp_to_non_negative(self) -> Self {
72        self.max(0.)
73    }
74}
75
76impl<T: Add<Output = T>> Add<NonNegative<T>> for NonNegative<T> {
77    type Output = Self;
78
79    fn add(self, other: Self) -> Self {
80        NonNegative(self.0 + other.0)
81    }
82}
83
84impl<T: Zero> Zero for NonNegative<T> {
85    fn is_zero(&self) -> bool {
86        self.0.is_zero()
87    }
88
89    fn zero() -> Self {
90        NonNegative(T::zero())
91    }
92}
93
94/// A wrapper of greater-than-or-equal-to-one values.
95#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
96#[derive(
97    Animate,
98    Clone,
99    ComputeSquaredDistance,
100    Copy,
101    Debug,
102    MallocSizeOf,
103    PartialEq,
104    PartialOrd,
105    SpecifiedValueInfo,
106    ToAnimatedZero,
107    ToComputedValue,
108    ToCss,
109    ToResolvedValue,
110    ToShmem,
111)]
112#[repr(transparent)]
113pub struct GreaterThanOrEqualToOne<T>(pub T);
114
115/// A wrapper of values between zero and one.
116#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
117#[derive(
118    Animate,
119    Clone,
120    ComputeSquaredDistance,
121    Copy,
122    Debug,
123    Hash,
124    MallocSizeOf,
125    PartialEq,
126    PartialOrd,
127    SpecifiedValueInfo,
128    ToAnimatedZero,
129    ToComputedValue,
130    ToCss,
131    ToResolvedValue,
132    ToShmem,
133)]
134#[repr(transparent)]
135pub struct ZeroToOne<T>(pub T);
136
137/// A clip rect for clip and image-region
138#[allow(missing_docs)]
139#[derive(
140    Clone,
141    ComputeSquaredDistance,
142    Copy,
143    Debug,
144    MallocSizeOf,
145    PartialEq,
146    SpecifiedValueInfo,
147    ToAnimatedValue,
148    ToAnimatedZero,
149    ToComputedValue,
150    ToCss,
151    ToResolvedValue,
152    ToShmem,
153)]
154#[css(function = "rect", comma)]
155#[repr(C)]
156pub struct GenericClipRect<LengthOrAuto> {
157    pub top: LengthOrAuto,
158    pub right: LengthOrAuto,
159    pub bottom: LengthOrAuto,
160    pub left: LengthOrAuto,
161}
162
163pub use self::GenericClipRect as ClipRect;
164
165/// Either a clip-rect or `auto`.
166#[allow(missing_docs)]
167#[derive(
168    Animate,
169    Clone,
170    ComputeSquaredDistance,
171    Copy,
172    Debug,
173    MallocSizeOf,
174    Parse,
175    PartialEq,
176    SpecifiedValueInfo,
177    ToAnimatedValue,
178    ToAnimatedZero,
179    ToComputedValue,
180    ToCss,
181    ToResolvedValue,
182    ToShmem,
183    ToTyped,
184)]
185#[repr(C, u8)]
186pub enum GenericClipRectOrAuto<R> {
187    Auto,
188    Rect(R),
189}
190
191pub use self::GenericClipRectOrAuto as ClipRectOrAuto;
192
193impl<L> ClipRectOrAuto<L> {
194    /// Returns the `auto` value.
195    #[inline]
196    pub fn auto() -> Self {
197        ClipRectOrAuto::Auto
198    }
199
200    /// Returns whether this value is the `auto` value.
201    #[inline]
202    pub fn is_auto(&self) -> bool {
203        matches!(*self, ClipRectOrAuto::Auto)
204    }
205}
206
207pub use page::PageSize;
208
209pub use text::NumberOrAuto;
210
211/// An optional value, much like `Option<T>`, but with a defined struct layout
212/// to be able to use it from C++ as well.
213///
214/// Note that this is relatively inefficient, struct-layout-wise, as you have
215/// one byte for the tag, but padding to the alignment of T. If you have
216/// multiple optional values and care about struct compactness, you might be
217/// better off "coalescing" the combinations into a parent enum. But that
218/// shouldn't matter for most use cases.
219#[allow(missing_docs)]
220#[derive(
221    Animate,
222    Clone,
223    ComputeSquaredDistance,
224    Copy,
225    Debug,
226    MallocSizeOf,
227    Parse,
228    PartialEq,
229    SpecifiedValueInfo,
230    ToAnimatedValue,
231    ToAnimatedZero,
232    ToComputedValue,
233    ToCss,
234    ToResolvedValue,
235    ToShmem,
236    Serialize,
237    Deserialize,
238)]
239#[repr(C, u8)]
240pub enum Optional<T> {
241    #[css(skip)]
242    None,
243    Some(T),
244}
245
246impl<T> Optional<T> {
247    /// Returns whether this value is present.
248    pub fn is_some(&self) -> bool {
249        matches!(*self, Self::Some(..))
250    }
251
252    /// Returns whether this value is not present.
253    pub fn is_none(&self) -> bool {
254        matches!(*self, Self::None)
255    }
256
257    /// Turns this Optional<> into a regular rust Option<>.
258    pub fn into_rust(self) -> Option<T> {
259        match self {
260            Self::Some(v) => Some(v),
261            Self::None => None,
262        }
263    }
264
265    /// Return a reference to the containing value, if any, as a plain rust
266    /// Option<>.
267    pub fn as_ref(&self) -> Option<&T> {
268        match *self {
269            Self::Some(ref v) => Some(v),
270            Self::None => None,
271        }
272    }
273
274    /// Return a mutable reference to the containing value, if any, as a plain
275    /// rust Option<>.
276    pub fn as_mut(&mut self) -> Option<&mut T> {
277        match *self {
278            Self::Some(ref mut v) => Some(v),
279            Self::None => None,
280        }
281    }
282
283    /// See Option::map.
284    pub fn map<U>(self, map: impl FnOnce(T) -> U) -> Optional<U> {
285        match self {
286            Self::Some(v) => Optional::Some(map(v)),
287            Self::None => Optional::None,
288        }
289    }
290}
291
292impl<T> From<Option<T>> for Optional<T> {
293    fn from(rust: Option<T>) -> Self {
294        match rust {
295            Some(t) => Self::Some(t),
296            None => Self::None,
297        }
298    }
299}