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
64impl<T: Add<Output = T>> Add<NonNegative<T>> for NonNegative<T> {
65    type Output = Self;
66
67    fn add(self, other: Self) -> Self {
68        NonNegative(self.0 + other.0)
69    }
70}
71
72impl<T: Zero> Zero for NonNegative<T> {
73    fn is_zero(&self) -> bool {
74        self.0.is_zero()
75    }
76
77    fn zero() -> Self {
78        NonNegative(T::zero())
79    }
80}
81
82/// A wrapper of greater-than-or-equal-to-one values.
83#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
84#[derive(
85    Animate,
86    Clone,
87    ComputeSquaredDistance,
88    Copy,
89    Debug,
90    MallocSizeOf,
91    PartialEq,
92    PartialOrd,
93    SpecifiedValueInfo,
94    ToAnimatedZero,
95    ToComputedValue,
96    ToCss,
97    ToResolvedValue,
98    ToShmem,
99)]
100#[repr(transparent)]
101pub struct GreaterThanOrEqualToOne<T>(pub T);
102
103/// A wrapper of values between zero and one.
104#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
105#[derive(
106    Animate,
107    Clone,
108    ComputeSquaredDistance,
109    Copy,
110    Debug,
111    Hash,
112    MallocSizeOf,
113    PartialEq,
114    PartialOrd,
115    SpecifiedValueInfo,
116    ToAnimatedZero,
117    ToComputedValue,
118    ToCss,
119    ToResolvedValue,
120    ToShmem,
121)]
122#[repr(transparent)]
123pub struct ZeroToOne<T>(pub T);
124
125/// A clip rect for clip and image-region
126#[allow(missing_docs)]
127#[derive(
128    Clone,
129    ComputeSquaredDistance,
130    Copy,
131    Debug,
132    MallocSizeOf,
133    PartialEq,
134    SpecifiedValueInfo,
135    ToAnimatedValue,
136    ToAnimatedZero,
137    ToComputedValue,
138    ToCss,
139    ToResolvedValue,
140    ToShmem,
141)]
142#[css(function = "rect", comma)]
143#[repr(C)]
144pub struct GenericClipRect<LengthOrAuto> {
145    pub top: LengthOrAuto,
146    pub right: LengthOrAuto,
147    pub bottom: LengthOrAuto,
148    pub left: LengthOrAuto,
149}
150
151pub use self::GenericClipRect as ClipRect;
152
153/// Either a clip-rect or `auto`.
154#[allow(missing_docs)]
155#[derive(
156    Animate,
157    Clone,
158    ComputeSquaredDistance,
159    Copy,
160    Debug,
161    MallocSizeOf,
162    Parse,
163    PartialEq,
164    SpecifiedValueInfo,
165    ToAnimatedValue,
166    ToAnimatedZero,
167    ToComputedValue,
168    ToCss,
169    ToResolvedValue,
170    ToShmem,
171    ToTyped,
172)]
173#[repr(C, u8)]
174pub enum GenericClipRectOrAuto<R> {
175    Auto,
176    Rect(R),
177}
178
179pub use self::GenericClipRectOrAuto as ClipRectOrAuto;
180
181impl<L> ClipRectOrAuto<L> {
182    /// Returns the `auto` value.
183    #[inline]
184    pub fn auto() -> Self {
185        ClipRectOrAuto::Auto
186    }
187
188    /// Returns whether this value is the `auto` value.
189    #[inline]
190    pub fn is_auto(&self) -> bool {
191        matches!(*self, ClipRectOrAuto::Auto)
192    }
193}
194
195pub use page::PageSize;
196
197pub use text::NumberOrAuto;
198
199/// An optional value, much like `Option<T>`, but with a defined struct layout
200/// to be able to use it from C++ as well.
201///
202/// Note that this is relatively inefficient, struct-layout-wise, as you have
203/// one byte for the tag, but padding to the alignment of T. If you have
204/// multiple optional values and care about struct compactness, you might be
205/// better off "coalescing" the combinations into a parent enum. But that
206/// shouldn't matter for most use cases.
207#[allow(missing_docs)]
208#[derive(
209    Animate,
210    Clone,
211    ComputeSquaredDistance,
212    Copy,
213    Debug,
214    MallocSizeOf,
215    Parse,
216    PartialEq,
217    SpecifiedValueInfo,
218    ToAnimatedValue,
219    ToAnimatedZero,
220    ToComputedValue,
221    ToCss,
222    ToResolvedValue,
223    ToShmem,
224    Serialize,
225    Deserialize,
226)]
227#[repr(C, u8)]
228pub enum Optional<T> {
229    #[css(skip)]
230    None,
231    Some(T),
232}
233
234impl<T> Optional<T> {
235    /// Returns whether this value is present.
236    pub fn is_some(&self) -> bool {
237        matches!(*self, Self::Some(..))
238    }
239
240    /// Returns whether this value is not present.
241    pub fn is_none(&self) -> bool {
242        matches!(*self, Self::None)
243    }
244
245    /// Turns this Optional<> into a regular rust Option<>.
246    pub fn into_rust(self) -> Option<T> {
247        match self {
248            Self::Some(v) => Some(v),
249            Self::None => None,
250        }
251    }
252
253    /// Return a reference to the containing value, if any, as a plain rust
254    /// Option<>.
255    pub fn as_ref(&self) -> Option<&T> {
256        match *self {
257            Self::Some(ref v) => Some(v),
258            Self::None => None,
259        }
260    }
261
262    /// Return a mutable reference to the containing value, if any, as a plain
263    /// rust Option<>.
264    pub fn as_mut(&mut self) -> Option<&mut T> {
265        match *self {
266            Self::Some(ref mut v) => Some(v),
267            Self::None => None,
268        }
269    }
270}
271
272impl<T> From<Option<T>> for Optional<T> {
273    fn from(rust: Option<T>) -> Self {
274        match rust {
275            Some(t) => Self::Some(t),
276            None => Self::None,
277        }
278    }
279}