2020-12-15 10:53:31 +00:00
|
|
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
2017-11-11 10:21:55 +00:00
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
use crate::ClockTime;
|
|
|
|
use crate::Format;
|
2020-10-27 17:27:16 +00:00
|
|
|
use glib::translate::{FromGlib, GlibNoneError, IntoGlib, OptionIntoGlib, TryFromGlib};
|
2017-12-09 16:20:21 +00:00
|
|
|
use muldiv::MulDiv;
|
2020-10-27 17:27:16 +00:00
|
|
|
use std::borrow::Borrow;
|
2019-06-03 15:42:00 +00:00
|
|
|
use std::convert::TryFrom;
|
2020-10-27 17:27:16 +00:00
|
|
|
use std::fmt;
|
2018-04-01 08:30:03 +00:00
|
|
|
use std::ops;
|
2020-05-26 15:52:49 +00:00
|
|
|
use thiserror::Error;
|
2017-11-11 10:21:55 +00:00
|
|
|
|
|
|
|
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
|
2020-11-21 13:46:48 +00:00
|
|
|
#[cfg_attr(feature = "ser_de", derive(serde::Serialize, serde::Deserialize))]
|
2017-12-09 16:20:21 +00:00
|
|
|
pub enum GenericFormattedValue {
|
2019-06-03 15:42:00 +00:00
|
|
|
Undefined(Undefined),
|
2020-10-27 17:27:16 +00:00
|
|
|
Default(Option<Default>),
|
|
|
|
Bytes(Option<Bytes>),
|
|
|
|
Time(Option<ClockTime>),
|
|
|
|
Buffers(Option<Buffers>),
|
|
|
|
Percent(Option<Percent>),
|
2017-11-11 10:21:55 +00:00
|
|
|
Other(Format, i64),
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:42:00 +00:00
|
|
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
|
|
|
pub struct Undefined(pub i64);
|
2020-10-13 15:17:46 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
|
|
|
pub struct Default(pub u64);
|
2020-10-13 15:17:46 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
|
|
|
pub struct Bytes(pub u64);
|
2020-10-13 15:17:46 +00:00
|
|
|
|
2019-06-03 15:42:00 +00:00
|
|
|
pub type Time = ClockTime;
|
2020-10-13 15:17:46 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
|
|
|
pub struct Buffers(pub u64);
|
|
|
|
impl Buffers {
|
|
|
|
pub const OFFSET_NONE: u64 = ffi::GST_BUFFER_OFFSET_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
|
|
|
pub struct Percent(pub u32);
|
|
|
|
impl Percent {
|
|
|
|
pub const MAX: u32 = ffi::GST_FORMAT_PERCENT_MAX as u32;
|
|
|
|
pub const SCALE: u32 = ffi::GST_FORMAT_PERCENT_SCALE as u32;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for GenericFormattedValue {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
use crate::utils::Displayable;
|
2020-10-13 15:17:46 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
match self {
|
|
|
|
Self::Undefined(val) => val.fmt(f),
|
|
|
|
Self::Default(val) => val.display().fmt(f),
|
|
|
|
Self::Bytes(val) => val.display().fmt(f),
|
|
|
|
Self::Time(val) => val.display().fmt(f),
|
|
|
|
Self::Buffers(val) => val.display().fmt(f),
|
|
|
|
Self::Percent(val) => val.display().fmt(f),
|
|
|
|
Self::Other(format, val) => write!(f, "{} ({:?})", val, format),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-05-26 15:52:49 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Error)]
|
|
|
|
#[error("invalid generic value format")]
|
2019-06-03 15:42:00 +00:00
|
|
|
pub struct TryFromGenericFormattedValueError(());
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2019-06-03 15:42:00 +00:00
|
|
|
pub trait FormattedValue: Copy + Clone + Sized + Into<GenericFormattedValue> + 'static {
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_default_format")]
|
2021-04-20 10:23:24 +00:00
|
|
|
fn default_format() -> Format;
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_format")]
|
2021-04-11 19:39:50 +00:00
|
|
|
fn format(&self) -> Format;
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2017-12-10 10:10:25 +00:00
|
|
|
unsafe fn from_raw(format: Format, value: i64) -> Self;
|
2020-10-27 17:27:16 +00:00
|
|
|
unsafe fn into_raw_value(self) -> i64;
|
|
|
|
}
|
|
|
|
|
|
|
|
// rustdoc-stripper-ignore-next
|
|
|
|
/// A trait implemented on the intrinsic type of a `FormattedValue`.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// - `GenericFormattedValue` is the intrinsic type for `GenericFormattedValue`.
|
|
|
|
/// - `Undefined` is the intrinsic type for `Undefined`.
|
|
|
|
/// - `Bytes` is the intrinsic type for `Option<Bytes>`.
|
|
|
|
pub trait FormattedValueIntrinsic: Copy + Clone + Sized + 'static {
|
|
|
|
type FormattedValueType: FormattedValue;
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
|
2019-06-03 15:42:00 +00:00
|
|
|
pub trait SpecificFormattedValue: FormattedValue + TryFrom<GenericFormattedValue> {}
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
// rustdoc-stripper-ignore-next
|
|
|
|
/// A trait implemented on the intrinsic type of a `SpecificFormattedValue`.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// - `Undefined` is the intrinsic type for `Undefined`.
|
|
|
|
/// - `Bytes` is the intrinsic type for `Option<Bytes>`.
|
|
|
|
pub trait SpecificFormattedValueIntrinsic: TryFromGlib<i64> + FormattedValueIntrinsic {}
|
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
impl FormattedValue for GenericFormattedValue {
|
2021-04-20 10:23:24 +00:00
|
|
|
fn default_format() -> Format {
|
2017-12-09 16:20:21 +00:00
|
|
|
Format::Undefined
|
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
fn format(&self) -> Format {
|
|
|
|
self.format()
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
|
2017-12-10 10:10:25 +00:00
|
|
|
unsafe fn from_raw(format: Format, value: i64) -> Self {
|
2017-12-09 16:20:21 +00:00
|
|
|
GenericFormattedValue::new(format, value)
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
unsafe fn into_raw_value(self) -> i64 {
|
2021-04-11 19:39:50 +00:00
|
|
|
self.value()
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GenericFormattedValue {
|
2017-11-11 10:21:55 +00:00
|
|
|
pub fn new(format: Format, value: i64) -> Self {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2017-11-11 10:21:55 +00:00
|
|
|
match format {
|
2021-04-29 20:52:33 +00:00
|
|
|
Format::Undefined => Self::Undefined(Undefined(value)),
|
2020-10-27 17:27:16 +00:00
|
|
|
Format::Default => Self::Default(unsafe { FromGlib::from_glib(value as u64) }),
|
|
|
|
Format::Bytes => Self::Bytes(unsafe { FromGlib::from_glib(value as u64) }),
|
|
|
|
Format::Time => Self::Time(unsafe { FromGlib::from_glib(value as u64) }),
|
|
|
|
Format::Buffers => Self::Buffers(unsafe { FromGlib::from_glib(value as u64) }),
|
|
|
|
Format::Percent => Self::Percent(unsafe { FormattedValue::from_raw(format, value) }),
|
2021-04-29 20:52:33 +00:00
|
|
|
Format::__Unknown(_) => Self::Other(format, value),
|
2017-11-11 10:21:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_format")]
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn format(&self) -> Format {
|
2017-11-11 10:21:55 +00:00
|
|
|
match *self {
|
2021-04-29 20:52:33 +00:00
|
|
|
Self::Undefined(_) => Format::Undefined,
|
|
|
|
Self::Default(_) => Format::Default,
|
|
|
|
Self::Bytes(_) => Format::Bytes,
|
|
|
|
Self::Time(_) => Format::Time,
|
|
|
|
Self::Buffers(_) => Format::Buffers,
|
|
|
|
Self::Percent(_) => Format::Percent,
|
|
|
|
Self::Other(f, _) => f,
|
2017-11-11 10:21:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_value")]
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn value(&self) -> i64 {
|
2020-10-27 17:27:16 +00:00
|
|
|
unsafe {
|
|
|
|
match *self {
|
|
|
|
Self::Undefined(v) => v.0,
|
|
|
|
Self::Default(v) => v.into_raw_value(),
|
|
|
|
Self::Bytes(v) => v.into_raw_value(),
|
|
|
|
Self::Time(v) => v.into_raw_value(),
|
|
|
|
Self::Buffers(v) => v.into_raw_value(),
|
|
|
|
Self::Percent(v) => v.into_raw_value(),
|
|
|
|
Self::Other(_, v) => v,
|
|
|
|
}
|
2017-11-11 10:21:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl FormattedValueIntrinsic for GenericFormattedValue {
|
|
|
|
type FormattedValueType = GenericFormattedValue;
|
|
|
|
}
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
macro_rules! impl_op_same(
|
|
|
|
($name:ident, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident) => {
|
|
|
|
impl<RHS: Borrow<$name>> ops::$op<RHS> for $name {
|
|
|
|
type Output = Self;
|
2019-06-03 08:13:32 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn $op_name(self, rhs: RHS) -> Self::Output {
|
|
|
|
Self(self.0.$op_name(rhs.borrow().0))
|
2019-06-03 08:13:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl<RHS: Borrow<$name>> ops::$op<RHS> for &$name {
|
2019-06-03 08:13:32 +00:00
|
|
|
type Output = $name;
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn $op_name(self, rhs: RHS) -> Self::Output {
|
|
|
|
(*self).$op_name(rhs)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl<RHS: Borrow<$name>> ops::$op_assign<RHS> for $name {
|
|
|
|
fn $op_assign_name(&mut self, rhs: RHS) {
|
|
|
|
self.0.$op_assign_name(rhs.borrow().0)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
);
|
|
|
|
|
|
|
|
macro_rules! impl_op_u64(
|
2020-10-27 17:27:16 +00:00
|
|
|
($name:ident, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident) => {
|
2017-12-09 16:20:21 +00:00
|
|
|
impl ops::$op<u64> for $name {
|
|
|
|
type Output = $name;
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn $op_name(self, rhs: u64) -> Self::Output {
|
|
|
|
$name(self.0.$op_name(rhs))
|
2019-06-03 08:13:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl ops::$op<u64> for &$name {
|
2019-06-03 08:13:32 +00:00
|
|
|
type Output = $name;
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn $op_name(self, rhs: u64) -> Self::Output {
|
|
|
|
(*self).$op_name(rhs)
|
2019-06-03 08:13:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::$op<$name> for u64 {
|
|
|
|
type Output = $name;
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn $op_name(self, rhs: $name) -> $name {
|
|
|
|
$name(self.$op_name(rhs.0))
|
2019-06-03 08:13:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl ops::$op<&$name> for u64 {
|
2019-06-03 08:13:32 +00:00
|
|
|
type Output = $name;
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn $op_name(self, rhs: &$name) -> $name {
|
|
|
|
self.$op_name(*rhs)
|
2019-06-03 08:13:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
impl ops::$op_assign<u64> for $name {
|
2020-10-27 17:27:16 +00:00
|
|
|
fn $op_assign_name(&mut self, rhs: u64) {
|
|
|
|
self.0.$op_assign_name(rhs)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
);
|
|
|
|
|
|
|
|
macro_rules! impl_format_value_traits(
|
|
|
|
($name:ident, $format:ident, $format_value:ident) => {
|
2020-10-27 17:27:16 +00:00
|
|
|
impl FormattedValue for Option<$name> {
|
2021-04-20 10:23:24 +00:00
|
|
|
fn default_format() -> Format {
|
2017-12-09 16:20:21 +00:00
|
|
|
Format::$format
|
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
fn format(&self) -> Format {
|
2017-12-09 16:20:21 +00:00
|
|
|
Format::$format
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
unsafe fn from_raw(format: Format, value: i64) -> Option<$name> {
|
2017-12-09 16:20:21 +00:00
|
|
|
debug_assert_eq!(format, Format::$format);
|
2020-10-27 17:27:16 +00:00
|
|
|
FromGlib::from_glib(value as u64)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
unsafe fn into_raw_value(self) -> i64 {
|
|
|
|
IntoGlib::into_glib(self) as i64
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Option<$name>> for GenericFormattedValue {
|
|
|
|
fn from(v: Option<$name>) -> Self {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
Self::$format_value(v)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:42:00 +00:00
|
|
|
impl From<$name> for GenericFormattedValue {
|
2021-01-08 10:43:18 +00:00
|
|
|
fn from(v: $name) -> Self {
|
2020-10-27 17:27:16 +00:00
|
|
|
skip_assert_initialized!();
|
|
|
|
Self::$format_value(Some(v))
|
2019-06-03 15:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl FormattedValueIntrinsic for $name {
|
|
|
|
type FormattedValueType = Option<$name>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TryFrom<GenericFormattedValue> for Option<$name> {
|
2019-06-03 15:42:00 +00:00
|
|
|
type Error = TryFromGenericFormattedValueError;
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn try_from(v: GenericFormattedValue) -> Result<Option<$name>, Self::Error> {
|
2021-01-07 19:47:31 +00:00
|
|
|
skip_assert_initialized!();
|
2019-06-03 15:42:00 +00:00
|
|
|
if let GenericFormattedValue::$format_value(v) = v {
|
|
|
|
Ok(v)
|
|
|
|
} else {
|
|
|
|
Err(TryFromGenericFormattedValueError(()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl TryFrom<u64> for $name {
|
|
|
|
type Error = GlibNoneError;
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn try_from(v: u64) -> Result<$name, GlibNoneError> {
|
2021-01-07 19:47:31 +00:00
|
|
|
skip_assert_initialized!();
|
2020-10-27 17:27:16 +00:00
|
|
|
unsafe { Self::try_from_glib(v) }
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl TryFromGlib<i64> for $name {
|
|
|
|
type Error = GlibNoneError;
|
|
|
|
#[inline]
|
|
|
|
unsafe fn try_from_glib(val: i64) -> Result<Self, GlibNoneError> {
|
2021-01-07 19:47:31 +00:00
|
|
|
skip_assert_initialized!();
|
2020-10-27 17:27:16 +00:00
|
|
|
<$name as TryFromGlib<u64>>::try_from_glib(val as u64)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl SpecificFormattedValue for Option<$name> {}
|
|
|
|
impl SpecificFormattedValueIntrinsic for $name {}
|
2017-12-09 16:20:21 +00:00
|
|
|
|
|
|
|
impl ops::Deref for $name {
|
2020-10-27 17:27:16 +00:00
|
|
|
type Target = u64;
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn deref(&self) -> &u64 {
|
2017-12-09 16:20:21 +00:00
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::DerefMut for $name {
|
2020-10-27 17:27:16 +00:00
|
|
|
fn deref_mut(&mut self) -> &mut u64 {
|
2017-12-09 16:20:21 +00:00
|
|
|
&mut self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl AsRef<u64> for $name {
|
|
|
|
fn as_ref(&self) -> &u64 {
|
2017-12-09 16:20:21 +00:00
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl AsMut<u64> for $name {
|
|
|
|
fn as_mut(&mut self) -> &mut u64 {
|
2017-12-09 16:20:21 +00:00
|
|
|
&mut self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl_op_same!($name, Add, add, AddAssign, add_assign);
|
|
|
|
impl_op_same!($name, Sub, sub, SubAssign, sub_assign);
|
|
|
|
impl_op_same!($name, Mul, mul, MulAssign, mul_assign);
|
|
|
|
impl_op_same!($name, Div, div, DivAssign, div_assign);
|
|
|
|
impl_op_same!($name, Rem, rem, RemAssign, rem_assign);
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl_op_u64!($name, Mul, mul, MulAssign, mul_assign);
|
|
|
|
impl_op_u64!($name, Div, div, DivAssign, div_assign);
|
|
|
|
impl_op_u64!($name, Rem, rem, RemAssign, rem_assign);
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl<ND: Borrow<u64>> MulDiv<ND> for $name {
|
2017-12-09 16:20:21 +00:00
|
|
|
type Output = $name;
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn mul_div_floor(self, num: ND, denom: ND) -> Option<Self::Output> {
|
|
|
|
self.0
|
|
|
|
.mul_div_floor(*num.borrow(), *denom.borrow())
|
|
|
|
.map($name)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn mul_div_round(self, num: ND, denom: ND) -> Option<Self::Output> {
|
|
|
|
self.0
|
|
|
|
.mul_div_round(*num.borrow(), *denom.borrow())
|
|
|
|
.map($name)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn mul_div_ceil(self, num: ND, denom: ND) -> Option<Self::Output> {
|
|
|
|
self.0
|
|
|
|
.mul_div_ceil(*num.borrow(), *denom.borrow())
|
|
|
|
.map($name)
|
2017-12-09 16:20:21 +00:00
|
|
|
}
|
|
|
|
}
|
2020-10-27 17:27:16 +00:00
|
|
|
};
|
|
|
|
);
|
2019-06-03 08:13:32 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
macro_rules! option_glib_newtype_display {
|
|
|
|
($name:ident, $unit:expr) => {
|
|
|
|
impl crate::utils::Displayable for Option<$name> {
|
|
|
|
type DisplayImpl = String;
|
2019-06-03 08:13:32 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn display(self) -> String {
|
|
|
|
if let Some(val) = self {
|
|
|
|
val.display()
|
|
|
|
} else {
|
|
|
|
format!("undef. {}", $unit)
|
|
|
|
}
|
2019-06-03 08:13:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl crate::utils::Displayable for $name {
|
|
|
|
type DisplayImpl = String;
|
2019-06-03 08:13:32 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn display(self) -> String {
|
|
|
|
format!("{} {}", self.0, $unit)
|
2019-06-03 08:13:32 +00:00
|
|
|
}
|
|
|
|
}
|
2017-12-09 16:20:21 +00:00
|
|
|
};
|
2020-10-27 17:27:16 +00:00
|
|
|
}
|
2017-12-09 16:20:21 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl_common_ops_for_newtype_u64!(Default);
|
2017-12-09 16:20:21 +00:00
|
|
|
impl_format_value_traits!(Default, Default, Default);
|
2020-10-27 17:27:16 +00:00
|
|
|
option_glib_newtype_from_to!(Default, u64::MAX);
|
|
|
|
option_glib_newtype_display!(Default, "(Default)");
|
|
|
|
|
|
|
|
impl_common_ops_for_newtype_u64!(Bytes);
|
2017-12-09 16:20:21 +00:00
|
|
|
impl_format_value_traits!(Bytes, Bytes, Bytes);
|
2020-10-27 17:27:16 +00:00
|
|
|
option_glib_newtype_from_to!(Bytes, u64::MAX);
|
|
|
|
option_glib_newtype_display!(Bytes, "bytes");
|
|
|
|
|
2017-12-09 16:20:21 +00:00
|
|
|
impl_format_value_traits!(ClockTime, Time, Time);
|
2020-10-27 17:27:16 +00:00
|
|
|
|
|
|
|
impl_common_ops_for_newtype_u64!(Buffers);
|
2017-12-09 16:20:21 +00:00
|
|
|
impl_format_value_traits!(Buffers, Buffers, Buffers);
|
2020-10-27 17:27:16 +00:00
|
|
|
option_glib_newtype_from_to!(Buffers, Buffers::OFFSET_NONE);
|
|
|
|
option_glib_newtype_display!(Buffers, "buffers");
|
2019-06-03 08:20:39 +00:00
|
|
|
|
2019-06-03 15:42:00 +00:00
|
|
|
impl FormattedValue for Undefined {
|
2021-04-20 10:23:24 +00:00
|
|
|
fn default_format() -> Format {
|
2019-06-03 15:42:00 +00:00
|
|
|
Format::Undefined
|
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
fn format(&self) -> Format {
|
2019-06-03 15:42:00 +00:00
|
|
|
Format::Undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn from_raw(format: Format, value: i64) -> Self {
|
|
|
|
debug_assert_eq!(format, Format::Undefined);
|
|
|
|
Undefined(value)
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
unsafe fn into_raw_value(self) -> i64 {
|
2019-06-03 15:42:00 +00:00
|
|
|
self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Undefined> for GenericFormattedValue {
|
2021-01-08 10:43:18 +00:00
|
|
|
fn from(v: Undefined) -> Self {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-06-03 15:42:00 +00:00
|
|
|
GenericFormattedValue::Undefined(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TryFrom<GenericFormattedValue> for Undefined {
|
|
|
|
type Error = TryFromGenericFormattedValueError;
|
|
|
|
|
|
|
|
fn try_from(v: GenericFormattedValue) -> Result<Undefined, TryFromGenericFormattedValueError> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-06-03 15:42:00 +00:00
|
|
|
if let GenericFormattedValue::Undefined(v) = v {
|
|
|
|
Ok(v)
|
|
|
|
} else {
|
|
|
|
Err(TryFromGenericFormattedValueError(()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl FormattedValueIntrinsic for Undefined {
|
|
|
|
type FormattedValueType = Undefined;
|
|
|
|
}
|
|
|
|
|
2019-06-03 15:42:00 +00:00
|
|
|
impl SpecificFormattedValue for Undefined {}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl SpecificFormattedValueIntrinsic for Undefined {}
|
|
|
|
|
|
|
|
impl TryFromGlib<i64> for Undefined {
|
|
|
|
type Error = std::convert::Infallible;
|
|
|
|
#[inline]
|
|
|
|
unsafe fn try_from_glib(v: i64) -> Result<Self, Self::Error> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2020-10-27 17:27:16 +00:00
|
|
|
Ok(Undefined(v))
|
2019-06-03 15:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl From<i64> for Undefined {
|
|
|
|
fn from(v: i64) -> Self {
|
2021-01-07 19:47:31 +00:00
|
|
|
skip_assert_initialized!();
|
2020-10-27 17:27:16 +00:00
|
|
|
Undefined(v)
|
2019-06-03 15:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::Deref for Undefined {
|
|
|
|
type Target = i64;
|
|
|
|
|
|
|
|
fn deref(&self) -> &i64 {
|
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::DerefMut for Undefined {
|
|
|
|
fn deref_mut(&mut self) -> &mut i64 {
|
|
|
|
&mut self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsRef<i64> for Undefined {
|
|
|
|
fn as_ref(&self) -> &i64 {
|
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsMut<i64> for Undefined {
|
|
|
|
fn as_mut(&mut self) -> &mut i64 {
|
|
|
|
&mut self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl fmt::Display for Undefined {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "{} (Undefined)", self.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl crate::utils::Displayable for Undefined {
|
|
|
|
type DisplayImpl = Undefined;
|
|
|
|
|
|
|
|
fn display(self) -> Undefined {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_common_ops_for_newtype_u64!(Percent);
|
|
|
|
option_glib_newtype_display!(Percent, "%");
|
|
|
|
|
|
|
|
impl FormattedValue for Option<Percent> {
|
2021-04-20 10:23:24 +00:00
|
|
|
fn default_format() -> Format {
|
2019-06-03 15:42:00 +00:00
|
|
|
Format::Percent
|
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
fn format(&self) -> Format {
|
2019-06-03 15:42:00 +00:00
|
|
|
Format::Percent
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn from_raw(format: Format, value: i64) -> Self {
|
|
|
|
debug_assert_eq!(format, Format::Percent);
|
2020-10-27 17:27:16 +00:00
|
|
|
Percent::try_from_glib(value as i64).ok()
|
2019-06-03 15:42:00 +00:00
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
unsafe fn into_raw_value(self) -> i64 {
|
|
|
|
self.map_or(-1, |v| v.0 as i64)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Option<Percent>> for GenericFormattedValue {
|
|
|
|
fn from(v: Option<Percent>) -> Self {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
GenericFormattedValue::Percent(v)
|
2019-06-03 15:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Percent> for GenericFormattedValue {
|
2021-01-08 10:43:18 +00:00
|
|
|
fn from(v: Percent) -> Self {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2020-10-27 17:27:16 +00:00
|
|
|
GenericFormattedValue::Percent(Some(v))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TryFromGlib<i64> for Percent {
|
|
|
|
type Error = GlibNoneError;
|
|
|
|
#[inline]
|
|
|
|
unsafe fn try_from_glib(value: i64) -> Result<Self, Self::Error> {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
if value < 0 || value > ffi::GST_FORMAT_PERCENT_MAX {
|
|
|
|
Err(GlibNoneError)
|
|
|
|
} else {
|
|
|
|
Ok(Percent(value as u32))
|
|
|
|
}
|
2019-06-03 15:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl TryFrom<GenericFormattedValue> for Option<Percent> {
|
2019-06-03 15:42:00 +00:00
|
|
|
type Error = TryFromGenericFormattedValueError;
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn try_from(
|
|
|
|
v: GenericFormattedValue,
|
|
|
|
) -> Result<Option<Percent>, TryFromGenericFormattedValueError> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-06-03 15:42:00 +00:00
|
|
|
if let GenericFormattedValue::Percent(v) = v {
|
|
|
|
Ok(v)
|
|
|
|
} else {
|
|
|
|
Err(TryFromGenericFormattedValueError(()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl FormattedValueIntrinsic for Percent {
|
|
|
|
type FormattedValueType = Option<Percent>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SpecificFormattedValue for Option<Percent> {}
|
|
|
|
|
|
|
|
impl SpecificFormattedValueIntrinsic for Percent {}
|
2019-06-03 15:42:00 +00:00
|
|
|
|
|
|
|
impl ops::Deref for Percent {
|
2020-10-27 17:27:16 +00:00
|
|
|
type Target = u32;
|
2019-06-03 15:42:00 +00:00
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
fn deref(&self) -> &u32 {
|
2019-06-03 15:42:00 +00:00
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::DerefMut for Percent {
|
2020-10-27 17:27:16 +00:00
|
|
|
fn deref_mut(&mut self) -> &mut u32 {
|
2019-06-03 15:42:00 +00:00
|
|
|
&mut self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl AsRef<u32> for Percent {
|
|
|
|
fn as_ref(&self) -> &u32 {
|
2019-06-03 15:42:00 +00:00
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-27 17:27:16 +00:00
|
|
|
impl AsMut<u32> for Percent {
|
|
|
|
fn as_mut(&mut self) -> &mut u32 {
|
2019-06-03 15:42:00 +00:00
|
|
|
&mut self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-26 15:52:49 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Error)]
|
|
|
|
#[error("value out of range")]
|
2019-06-03 15:42:00 +00:00
|
|
|
pub struct TryPercentFromFloatError(());
|
|
|
|
|
|
|
|
impl TryFrom<f64> for Percent {
|
|
|
|
type Error = TryPercentFromFloatError;
|
|
|
|
|
|
|
|
fn try_from(v: f64) -> Result<Self, Self::Error> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-06-03 15:42:00 +00:00
|
|
|
if v < 0.0 || v > 1.0 {
|
|
|
|
Err(TryPercentFromFloatError(()))
|
|
|
|
} else {
|
2020-10-27 17:27:16 +00:00
|
|
|
Ok(Percent(
|
|
|
|
(v * ffi::GST_FORMAT_PERCENT_SCALE as f64).round() as u32
|
|
|
|
))
|
2019-06-03 15:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TryFrom<f32> for Percent {
|
|
|
|
type Error = TryPercentFromFloatError;
|
|
|
|
|
|
|
|
fn try_from(v: f32) -> Result<Self, Self::Error> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-06-03 15:42:00 +00:00
|
|
|
if v < 0.0 || v > 1.0 {
|
|
|
|
Err(TryPercentFromFloatError(()))
|
|
|
|
} else {
|
2020-10-27 17:27:16 +00:00
|
|
|
Ok(Percent(
|
|
|
|
(v * ffi::GST_FORMAT_PERCENT_SCALE as f32).round() as u32
|
|
|
|
))
|
2019-06-03 15:42:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|