From 96fb1378d7307674b24ed4bcafdaa24dce3e1bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 2 Jan 2017 03:28:08 +0100 Subject: [PATCH] style: Document the sugar for `nsStyleCoord`. --- .../gecko_bindings/sugar/ns_style_coord.rs | 87 +++++++++++++++---- 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/components/style/gecko_bindings/sugar/ns_style_coord.rs b/components/style/gecko_bindings/sugar/ns_style_coord.rs index 9aac36e9915..84ea7d68456 100644 --- a/components/style/gecko_bindings/sugar/ns_style_coord.rs +++ b/components/style/gecko_bindings/sugar/ns_style_coord.rs @@ -2,6 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +//! Rust helpers for Gecko's `nsStyleCoord`. + use gecko_bindings::bindings::{Gecko_ResetStyleCoord, Gecko_SetStyleCoordCalcValue, Gecko_AddRefCalcArbitraryThread}; use gecko_bindings::structs::{nsStyleCoord_Calc, nsStyleUnit, nsStyleUnion, nsStyleCoord, nsStyleSides, nsStyleCorners}; use gecko_bindings::structs::{nsStyleCoord_CalcValue, nscoord}; @@ -9,6 +11,7 @@ use std::mem; impl nsStyleCoord { #[inline] + /// Get a `null` nsStyleCoord. pub fn null() -> Self { // Can't construct directly because it has private fields let mut coord: Self = unsafe { mem::zeroed() }; @@ -41,6 +44,7 @@ impl CoordDataMut for nsStyleCoord { } impl nsStyleCoord_CalcValue { + /// Create an "empty" CalcValue (whose value is `0`). pub fn new() -> Self { nsStyleCoord_CalcValue { mLength: 0, @@ -51,6 +55,8 @@ impl nsStyleCoord_CalcValue { } impl nsStyleSides { + /// Immutably get the `nsStyleCoord`-like object representing the side at + /// index `index`. #[inline] pub fn data_at(&self, index: usize) -> SidesData { SidesData { @@ -58,6 +64,9 @@ impl nsStyleSides { index: index, } } + + /// Mutably get the `nsStyleCoord`-like object representing the side at + /// index `index`. #[inline] pub fn data_at_mut(&mut self, index: usize) -> SidesDataMut { SidesDataMut { @@ -67,10 +76,15 @@ impl nsStyleSides { } } +/// A `nsStyleCoord`-like object on top of an immutable reference to +/// `nsStyleSides`. pub struct SidesData<'a> { sides: &'a nsStyleSides, index: usize, } + +/// A `nsStyleCoord`-like object on top of an mutable reference to +/// `nsStyleSides`. pub struct SidesDataMut<'a> { sides: &'a mut nsStyleSides, index: usize, @@ -113,6 +127,8 @@ impl<'a> CoordDataMut for SidesDataMut<'a> { } impl nsStyleCorners { + /// Get a `nsStyleCoord` like object representing the given index's value + /// and unit. #[inline] pub fn data_at(&self, index: usize) -> CornersData { CornersData { @@ -120,6 +136,9 @@ impl nsStyleCorners { index: index, } } + + /// Get a `nsStyleCoord` like object representing the mutable given index's + /// value and unit. #[inline] pub fn data_at_mut(&mut self, index: usize) -> CornersDataMut { CornersDataMut { @@ -129,10 +148,13 @@ impl nsStyleCorners { } } +/// A `nsStyleCoord`-like struct on top of `nsStyleCorners`. pub struct CornersData<'a> { corners: &'a nsStyleCorners, index: usize, } + +/// A `nsStyleCoord`-like struct on top of a mutable `nsStyleCorners` reference. pub struct CornersDataMut<'a> { corners: &'a mut nsStyleCorners, index: usize, @@ -172,36 +194,56 @@ impl<'a> CoordDataMut for CornersDataMut<'a> { #[derive(Copy, Clone)] /// Enum representing the tagged union that is CoordData. -/// In release mode this should never actually exist in the code, -/// and will be optimized out by threading matches and inlining. +/// +/// In release mode this should never actually exist in the code, and will be +/// optimized out by threading matches and inlining. pub enum CoordDataValue { + /// eStyleUnit_Null Null, + /// eStyleUnit_Normal Normal, + /// eStyleUnit_Auto Auto, + /// eStyleUnit_None None, + /// eStyleUnit_Percent Percent(f32), + /// eStyleUnit_Factor Factor(f32), + /// eStyleUnit_Degree Degree(f32), + /// eStyleUnit_Grad Grad(f32), + /// eStyleUnit_Radian Radian(f32), + /// eStyleUnit_Turn Turn(f32), + /// eStyleUnit_FlexFraction FlexFraction(f32), + /// eStyleUnit_Coord Coord(nscoord), + /// eStyleUnit_Integer Integer(i32), + /// eStyleUnit_Enumerated Enumerated(u32), + /// eStyleUnit_Calc Calc(nsStyleCoord_CalcValue), } +/// A trait to abstract on top of a mutable `nsStyleCoord`-like object. pub trait CoordDataMut : CoordData { - // This can't be two methods since we can't mutably borrow twice - /// This is unsafe since it's possible to modify - /// the unit without changing the union + /// Get mutably the unit and the union. + /// + /// This is unsafe since it's possible to modify the unit without changing + /// the union. + /// + /// NB: This can't be two methods since we can't mutably borrow twice unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion); - /// Clean up any resources used by the union - /// Currently, this only happens if the nsStyleUnit - /// is a Calc + /// Clean up any resources used by the union. + /// + /// Currently, this only happens if the nsStyleUnit is a Calc. #[inline] fn reset(&mut self) { unsafe { @@ -213,27 +255,26 @@ pub trait CoordDataMut : CoordData { } #[inline] + /// Copies the unit and value from another `CoordData` type. fn copy_from(&mut self, other: &T) { unsafe { self.reset(); - { - let (unit, union) = self.values_mut(); - *unit = other.unit(); - *union = other.union(); - } + self.copy_from_unchecked(other); self.addref_if_calc(); } } #[inline] + /// Copies the unit and value from another `CoordData` type without checking + /// the type of the value (so refcounted values like calc may leak). unsafe fn copy_from_unchecked(&mut self, other: &T) { - let (unit, union) = self.values_mut(); - *unit = other.unit(); - *union = other.union(); + let (unit, union) = self.values_mut(); + *unit = other.unit(); + *union = other.union(); } - /// Useful for initializing uninits - /// (set_value may segfault on uninits) + /// Useful for initializing uninits, given that `set_value` may segfault on + /// uninits. fn leaky_set_null(&mut self) { use gecko_bindings::structs::nsStyleUnit::*; unsafe { @@ -244,6 +285,7 @@ pub trait CoordDataMut : CoordData { } #[inline(always)] + /// Sets the inner value. fn set_value(&mut self, value: CoordDataValue) { use gecko_bindings::structs::nsStyleUnit::*; use self::CoordDataValue::*; @@ -316,12 +358,16 @@ pub trait CoordDataMut : CoordData { } #[inline] + /// Gets the `Calc` value mutably, asserts in debug builds if the unit is + /// not `Calc`. unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc { debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc); &mut *(*self.union().mPointer.as_mut() as *mut nsStyleCoord_Calc) } #[inline] + /// Does what it promises, if the unit is `calc`, it bumps the reference + /// count _of the calc expression_. fn addref_if_calc(&mut self) { unsafe { if self.unit() == nsStyleUnit::eStyleUnit_Calc { @@ -330,12 +376,16 @@ pub trait CoordDataMut : CoordData { } } } +/// A trait to abstract on top of a `nsStyleCoord`-like object. pub trait CoordData { + /// Get the unit of this object. fn unit(&self) -> nsStyleUnit; + /// Get the `nsStyleUnion` for this object. fn union(&self) -> nsStyleUnion; #[inline(always)] + /// Get the appropriate value for this object. fn as_value(&self) -> CoordDataValue { use gecko_bindings::structs::nsStyleUnit::*; use self::CoordDataValue::*; @@ -390,6 +440,7 @@ pub trait CoordData { #[inline] + /// Pretend the inner value is a calc expression, and obtain it. unsafe fn as_calc(&self) -> &nsStyleCoord_Calc { debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc); &*(*self.union().mPointer.as_ref() as *const nsStyleCoord_Calc)