gst/format: make from_u64 constructors const

This commit makes the formatted values' main constructors `const`,
so that they can be used in constant definitions.

`from_usize` constructors can't be made const because `try_into`
can't be used in `const` functions as of rustc 1.64.0. Same for
`Percent::from_ratio`: floating point arithmetic is not allowed.
This commit is contained in:
François Laignel 2022-10-18 11:10:27 +02:00
parent 384783b242
commit 49faa03c98
5 changed files with 54 additions and 18 deletions

View file

@ -199,6 +199,7 @@ impl Signed<ClockTime> {
impl_format_value_traits!(ClockTime, Time, Time, u64);
option_glib_newtype_from_to!(ClockTime, ffi::GST_CLOCK_TIME_NONE);
// FIXME `functions in traits cannot be const` (rustc 1.64.0)
// rustdoc-stripper-ignore-next
/// `ClockTime` formatted value constructor trait.
pub trait TimeFormatConstructor {

View file

@ -28,8 +28,12 @@ impl Other {
/// Panics if the provided quantity equals `u64::MAX`,
/// which is reserved for `None` in C.
#[track_caller]
pub fn from_u64(quantity: u64) -> Self {
Other::try_from(quantity).expect("`Other` value out of range")
pub const fn from_u64(quantity: u64) -> Self {
if quantity == u64::MAX {
panic!("`Other` value out of range");
}
Other(quantity)
}
// rustdoc-stripper-ignore-next
@ -41,6 +45,7 @@ impl Other {
/// which is reserved for `None` in C.
#[track_caller]
pub fn from_usize(quantity: usize) -> Self {
// FIXME can't use `try_into` in `const` (rustc 1.64.0)
Other::from_u64(quantity.try_into().unwrap())
}
}
@ -67,6 +72,7 @@ impl TryFromGlib<i64> for Other {
}
}
// FIXME `functions in traits cannot be const` (rustc 1.64.0)
// rustdoc-stripper-ignore-next
/// `Other` formatted value constructor trait.
pub trait OtherFormatConstructor {

View file

@ -74,26 +74,26 @@
//! assert_eq!(Default::try_from(42), Ok(default));
//! assert_eq!(Default::try_from(42).ok(), Some(default));
//!
//! // `ClockTime` provides specific constructors,
//! // `ClockTime` provides specific `const` constructors,
//! // which can panic if the requested value is out of range.
//! let time = ClockTime::from_nseconds(45_834_908_569_837);
//! let time = ClockTime::from_seconds(20);
//!
//! // Other formatted values also come with (panicking) constructors:
//! // Other formatted values also come with (panicking) `const` constructors:
//! let buffers_nb = Buffers::from_u64(512);
//! let received = Bytes::from_u64(64);
//! let quantity = Default::from_u64(42);
//!
//! // `Bytes` can be built from an `usize` too:
//! // `Bytes` can be built from an `usize` too (not `const`):
//! let sample_size = Bytes::from_usize([0u8; 4].len());
//!
//! // This can be convenient:
//! // This can be convenient (not `const`):
//! assert_eq!(
//! 7.seconds() + 250.mseconds(),
//! ClockTime::from_nseconds(7_250_000_000),
//! );
//!
//! // Those too:
//! // Those too (not `const`):
//! assert_eq!(512.buffers(), Buffers::from_u64(512));
//! assert_eq!(64.bytes(), Bytes::from_u64(64));
//! assert_eq!(42.default_format(), Default::from_u64(42));
@ -105,7 +105,7 @@
//! // Specific formatted values provide the constant `ONE` value:
//! assert_eq!(*Buffers::ONE, 1);
//!
//! // `Bytes` also comes with usual multipliers:
//! // `Bytes` also comes with usual multipliers (not `const`):
//! assert_eq!(*(512.kibibytes()), 512 * 1024);
//! assert_eq!(*(8.mebibytes()), 8 * 1024 * 1024);
//! assert_eq!(*(4.gibibytes()), 4 * 1024 * 1024 * 1024);

View file

@ -37,8 +37,12 @@ impl Buffers {
/// Panics if the provided count equals `u64::MAX`,
/// which is reserved for `None` in C.
#[track_caller]
pub fn from_u64(buffers: u64) -> Self {
Buffers::try_from(buffers).expect("`Buffers` value out of range")
pub const fn from_u64(buffers: u64) -> Self {
if buffers == ffi::GST_BUFFER_OFFSET_NONE {
panic!("`Buffers` value out of range");
}
Buffers(buffers)
}
// rustdoc-stripper-ignore-next
@ -60,6 +64,7 @@ impl_format_value_traits!(Buffers, Buffers, Buffers, u64);
option_glib_newtype_from_to!(Buffers, Buffers::OFFSET_NONE);
glib_newtype_display!(Buffers, DisplayableOptionBuffers, Format::Buffers);
// FIXME `functions in traits cannot be const` (rustc 1.64.0)
// rustdoc-stripper-ignore-next
/// `Buffers` formatted value constructor trait.
pub trait BuffersFormatConstructor {
@ -103,8 +108,12 @@ impl Bytes {
/// Panics if the provided count equals `u64::MAX`,
/// which is reserved for `None` in C.
#[track_caller]
pub fn from_u64(bytes: u64) -> Self {
Bytes::try_from(bytes).expect("`Bytes` value out of range")
pub const fn from_u64(bytes: u64) -> Self {
if bytes == u64::MAX {
panic!("`Bytes` value out of range");
}
Bytes(bytes)
}
// rustdoc-stripper-ignore-next
@ -116,6 +125,7 @@ impl Bytes {
/// which is reserved for `None` in C.
#[track_caller]
pub fn from_usize(bytes: usize) -> Self {
// FIXME can't use `try_into` in `const` (rustc 1.64.0)
Bytes::from_u64(bytes.try_into().unwrap())
}
}
@ -126,6 +136,7 @@ impl_format_value_traits!(Bytes, Bytes, Bytes, u64);
option_glib_newtype_from_to!(Bytes, u64::MAX);
glib_newtype_display!(Bytes, DisplayableOptionBytes, Format::Bytes);
// FIXME `functions in traits cannot be const` (rustc 1.64.0)
// rustdoc-stripper-ignore-next
/// `Bytes` formatted value constructor trait.
///
@ -187,8 +198,12 @@ impl Default {
/// Panics if the provided quantity equals `u64::MAX`,
/// which is reserved for `None` in C.
#[track_caller]
pub fn from_u64(quantity: u64) -> Self {
Default::try_from(quantity).expect("`Default` value out of range")
pub const fn from_u64(quantity: u64) -> Self {
if quantity == u64::MAX {
panic!("`Default` value out of range");
}
Default(quantity)
}
// rustdoc-stripper-ignore-next
@ -200,6 +215,7 @@ impl Default {
/// which is reserved for `None` in C.
#[track_caller]
pub fn from_usize(quantity: usize) -> Self {
// FIXME can't use `try_into` in `const` (rustc 1.64.0)
Default::from_u64(quantity.try_into().unwrap())
}
}
@ -210,6 +226,7 @@ impl_format_value_traits!(Default, Default, Default, u64);
option_glib_newtype_from_to!(Default, u64::MAX);
glib_newtype_display!(Default, DisplayableOptionDefault, Format::Default);
// FIXME `functions in traits cannot be const` (rustc 1.64.0)
// rustdoc-stripper-ignore-next
/// `Default` formatted value constructor trait.
pub trait DefaultFormatConstructor {
@ -242,8 +259,12 @@ impl Percent {
///
/// Panics if the provided value is larger than 100.
#[track_caller]
pub fn from_percent(percent: u32) -> Self {
Percent::try_from(*Self::SCALE * percent).expect("`Percent` value out of range")
pub const fn from_percent(percent: u32) -> Self {
if percent > 100 {
panic!("`Percent` value out of range");
}
Percent(ffi::GST_FORMAT_PERCENT_SCALE as u32 * percent)
}
// rustdoc-stripper-ignore-next
@ -253,8 +274,12 @@ impl Percent {
///
/// Panics if the provided value is larger than [`Self::MAX`].
#[track_caller]
pub fn from_ppm(ppm: u32) -> Self {
Percent::try_from(ppm).expect("`Percent` value out of range")
pub const fn from_ppm(ppm: u32) -> Self {
if ppm > ffi::GST_FORMAT_PERCENT_MAX as u32 {
panic!("`Percent` ppm value out of range");
}
Percent(ppm)
}
// rustdoc-stripper-ignore-next
@ -265,6 +290,7 @@ impl Percent {
/// Panics if the provided radio is out of the range [0.0, 1.0].
#[track_caller]
pub fn from_ratio(ratio: f32) -> Self {
// FIXME floating point arithmetic is not allowed in constant functions (rustc 1.64.0)
Percent::try_from(ratio).expect("`Percent` ratio out of range")
}
}
@ -425,6 +451,7 @@ impl TryFrom<f32> for Percent {
}
}
// FIXME `functions in traits cannot be const` (rustc 1.64.0)
// rustdoc-stripper-ignore-next
/// `Percent` formatted value from integer constructor trait.
pub trait PercentFormatIntegerConstructor {
@ -449,6 +476,7 @@ impl PercentFormatIntegerConstructor for u32 {
}
}
// FIXME `functions in traits cannot be const` (rustc 1.64.0)
// rustdoc-stripper-ignore-next
/// `Percent` formatted value from float constructor trait.
pub trait PercentFormatFloatConstructor {

View file

@ -14,6 +14,7 @@ impl Undefined {
pub const ONE: Undefined = Undefined(1);
}
// FIXME `functions in traits cannot be const` (rustc 1.64.0)
// rustdoc-stripper-ignore-next
/// `Undefined` formatted value constructor trait.
pub trait UndefinedFormatConstructor {