forked from mirrors/gstreamer-rs
format/Other: use u64 internally instead of i64
This commit is contained in:
parent
8a7813d04c
commit
04b6710f84
7 changed files with 293 additions and 144 deletions
|
@ -3,31 +3,45 @@
|
||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
|
|
||||||
use crate::format::{Buffers, Bytes, Default, Percent, Undefined};
|
use crate::format::{Buffers, Bytes, Default, Other, Percent, Undefined};
|
||||||
|
|
||||||
|
// FIXME: the ser/de impl assumed `GenericFormattedValue` was always used.
|
||||||
|
// When serializing a `SpecificFormattedValue`, we loose the type and only
|
||||||
|
// serialize the inner value in parenthesis.
|
||||||
// Manual implementation for some types that would otherwise yield representations such as:
|
// Manual implementation for some types that would otherwise yield representations such as:
|
||||||
// "Default((Some(42)))"
|
// "Default(Some((42)))"
|
||||||
macro_rules! impl_serde(
|
macro_rules! impl_serde(
|
||||||
($t:ident) => {
|
($t:ident, $inner:ty) => {
|
||||||
impl Serialize for $t {
|
impl Serialize for $t {
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
self.0.serialize(serializer)
|
use std::ops::Deref;
|
||||||
|
self.deref().serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for $t {
|
impl<'de> Deserialize<'de> for $t {
|
||||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
u64::deserialize(deserializer).map($t)
|
<$inner>::deserialize(deserializer)
|
||||||
|
.and_then(|value| {
|
||||||
|
$t::try_from(value).map_err(|_| {
|
||||||
|
use serde::de::{Error, Unexpected};
|
||||||
|
D::Error::invalid_value(
|
||||||
|
Unexpected::Unsigned(value.into()),
|
||||||
|
&concat!("valid ", stringify!($t)),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_serde!(Buffers);
|
impl_serde!(Buffers, u64);
|
||||||
impl_serde!(Bytes);
|
impl_serde!(Bytes, u64);
|
||||||
impl_serde!(Default);
|
impl_serde!(Default, u64);
|
||||||
|
impl_serde!(Other, u64);
|
||||||
|
impl_serde!(Percent, u32);
|
||||||
|
|
||||||
impl Serialize for Undefined {
|
impl Serialize for Undefined {
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
|
@ -42,22 +56,9 @@ impl<'de> Deserialize<'de> for Undefined {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for Percent {
|
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
||||||
self.0.serialize(serializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Percent {
|
|
||||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
|
||||||
skip_assert_initialized!();
|
|
||||||
u32::deserialize(deserializer).map(Percent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::format::{Buffers, Bytes, Default, Percent, Undefined};
|
use crate::format::{Buffers, Bytes, Default, Other, Percent, Undefined};
|
||||||
use crate::ClockTime;
|
use crate::ClockTime;
|
||||||
use crate::Format;
|
use crate::Format;
|
||||||
use crate::GenericFormattedValue;
|
use crate::GenericFormattedValue;
|
||||||
|
@ -110,15 +111,15 @@ mod tests {
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Percent\":4200}".to_owned(), res);
|
assert_eq!("{\"Percent\":4200}".to_owned(), res);
|
||||||
|
|
||||||
let value = GenericFormattedValue::Other(Format::Percent, 42);
|
let value = GenericFormattedValue::Other(Format::Percent, Other::try_from(42).ok());
|
||||||
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
|
||||||
assert_eq!(Ok("Other(Percent, 42)".to_owned()), res);
|
assert_eq!(Ok("Other(Percent, Some(42))".to_owned()), res);
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Other\":[\"Percent\",42]}".to_owned(), res);
|
assert_eq!("{\"Other\":[\"Percent\",42]}".to_owned(), res);
|
||||||
|
|
||||||
let value = GenericFormattedValue::Other(Format::__Unknown(7), 42);
|
let value = GenericFormattedValue::new(Format::__Unknown(7), 42);
|
||||||
let res = ron::ser::to_string_pretty(&value, pretty_config);
|
let res = ron::ser::to_string_pretty(&value, pretty_config);
|
||||||
assert_eq!(Ok("Other(__Unknown(7), 42)".to_owned()), res);
|
assert_eq!(Ok("Other(__Unknown(7), Some(42))".to_owned()), res);
|
||||||
let res = serde_json::to_string(&value).unwrap();
|
let res = serde_json::to_string(&value).unwrap();
|
||||||
assert_eq!("{\"Other\":[{\"__Unknown\":7},42]}".to_owned(), res);
|
assert_eq!("{\"Other\":[{\"__Unknown\":7},42]}".to_owned(), res);
|
||||||
}
|
}
|
||||||
|
@ -135,13 +136,15 @@ mod tests {
|
||||||
let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap();
|
let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap();
|
||||||
assert_eq!(value_de, GenericFormattedValue::from(Default(42)));
|
assert_eq!(value_de, GenericFormattedValue::from(Default(42)));
|
||||||
|
|
||||||
let value_ron = "Other(Percent, 42)";
|
let value_ron = "Other(Percent, Some(42))";
|
||||||
|
let gfv_value = GenericFormattedValue::Other(Format::Percent, Other::try_from(42).ok());
|
||||||
|
|
||||||
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap();
|
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap();
|
||||||
assert_eq!(value_de, GenericFormattedValue::Other(Format::Percent, 42));
|
assert_eq!(value_de, gfv_value);
|
||||||
|
|
||||||
let value_json = "{\"Other\":[\"Percent\",42]}";
|
let value_json = "{\"Other\":[\"Percent\",42]}";
|
||||||
let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap();
|
let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap();
|
||||||
assert_eq!(value_de, GenericFormattedValue::Other(Format::Percent, 42));
|
assert_eq!(value_de, gfv_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -166,7 +169,8 @@ mod tests {
|
||||||
test_roundrip!(GenericFormattedValue::from(
|
test_roundrip!(GenericFormattedValue::from(
|
||||||
Percent::try_from(0.42).unwrap()
|
Percent::try_from(0.42).unwrap()
|
||||||
));
|
));
|
||||||
test_roundrip!(GenericFormattedValue::Other(Format::Percent, 42));
|
let gfv_value = GenericFormattedValue::Other(Format::Percent, Other::try_from(42).ok());
|
||||||
test_roundrip!(GenericFormattedValue::Other(Format::__Unknown(7), 42));
|
test_roundrip!(gfv_value);
|
||||||
|
test_roundrip!(GenericFormattedValue::new(Format::__Unknown(7), 42));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Take a look at the license at the top of the repository in the LICENSE file.
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
use glib::translate::FromGlib;
|
use glib::translate::{FromGlib, GlibNoneError, IntoGlib, OptionIntoGlib, TryFromGlib};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::utils::Displayable;
|
use crate::utils::Displayable;
|
||||||
|
@ -10,9 +10,37 @@ use super::{
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
CompatibleFormattedValue, FormattedValue, FormattedValueFullRange, FormattedValueIntrinsic,
|
CompatibleFormattedValue, FormattedValue, FormattedValueFullRange, FormattedValueIntrinsic,
|
||||||
FormattedValueNoneBuilder, UnsignedIntoSigned,
|
FormattedValueNoneBuilder, SignedIntrinsic, UnsignedIntoSigned,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
||||||
|
pub struct Other(u64);
|
||||||
|
impl Other {
|
||||||
|
pub const MAX: Self = Self(u64::MAX - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_common_ops_for_newtype_uint!(Other, u64);
|
||||||
|
impl_signed_div_mul!(Other, u64);
|
||||||
|
option_glib_newtype_from_to!(Other, u64::MAX);
|
||||||
|
glib_newtype_display!(Other, DisplayableOther, DisplayableOptionOther);
|
||||||
|
|
||||||
|
impl TryFrom<u64> for Other {
|
||||||
|
type Error = GlibNoneError;
|
||||||
|
fn try_from(val: u64) -> Result<Self, GlibNoneError> {
|
||||||
|
skip_assert_initialized!();
|
||||||
|
unsafe { Self::try_from_glib(val) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFromGlib<i64> for Other {
|
||||||
|
type Error = GlibNoneError;
|
||||||
|
#[inline]
|
||||||
|
unsafe fn try_from_glib(val: i64) -> Result<Self, GlibNoneError> {
|
||||||
|
skip_assert_initialized!();
|
||||||
|
Self::try_from_glib(val as u64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub enum GenericFormattedValue {
|
pub enum GenericFormattedValue {
|
||||||
|
@ -22,7 +50,7 @@ pub enum GenericFormattedValue {
|
||||||
Time(Option<ClockTime>),
|
Time(Option<ClockTime>),
|
||||||
Buffers(Option<Buffers>),
|
Buffers(Option<Buffers>),
|
||||||
Percent(Option<Percent>),
|
Percent(Option<Percent>),
|
||||||
Other(Format, i64),
|
Other(Format, Option<Other>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for GenericFormattedValue {
|
impl fmt::Display for GenericFormattedValue {
|
||||||
|
@ -34,24 +62,33 @@ impl fmt::Display for GenericFormattedValue {
|
||||||
Self::Time(val) => val.display().fmt(f),
|
Self::Time(val) => val.display().fmt(f),
|
||||||
Self::Buffers(val) => val.display().fmt(f),
|
Self::Buffers(val) => val.display().fmt(f),
|
||||||
Self::Percent(val) => val.display().fmt(f),
|
Self::Percent(val) => val.display().fmt(f),
|
||||||
Self::Other(format, val) => write!(f, "{} ({:?})", val, format),
|
Self::Other(format, val) => {
|
||||||
|
val.display().fmt(f)?;
|
||||||
|
fmt::Write::write_char(f, ' ')?;
|
||||||
|
fmt::Display::fmt(&format, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Displayable for GenericFormattedValue {
|
||||||
|
type DisplayImpl = GenericFormattedValue;
|
||||||
|
fn display(self) -> Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GenericFormattedValue {
|
impl GenericFormattedValue {
|
||||||
pub fn new(format: Format, value: i64) -> Self {
|
pub fn new(format: Format, value: i64) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
match format {
|
match format {
|
||||||
Format::Undefined => Self::Undefined(Undefined(value)),
|
Format::Undefined => Self::Undefined(Undefined(value)),
|
||||||
Format::Default => Self::Default(unsafe { FromGlib::from_glib(value as u64) }),
|
Format::Default => Self::Default(unsafe { FromGlib::from_glib(value) }),
|
||||||
Format::Bytes => Self::Bytes(unsafe { FromGlib::from_glib(value as u64) }),
|
Format::Bytes => Self::Bytes(unsafe { FromGlib::from_glib(value) }),
|
||||||
Format::Time => Self::Time(unsafe { FromGlib::from_glib(value as u64) }),
|
Format::Time => Self::Time(unsafe { FromGlib::from_glib(value) }),
|
||||||
Format::Buffers => Self::Buffers(unsafe { FromGlib::from_glib(value as u64) }),
|
Format::Buffers => Self::Buffers(unsafe { FromGlib::from_glib(value) }),
|
||||||
Format::Percent => {
|
Format::Percent => Self::Percent(unsafe { FromGlib::from_glib(value) }),
|
||||||
Self::Percent(unsafe { FormattedValueFullRange::from_raw(format, value) })
|
Format::__Unknown(_) => Self::Other(format, unsafe { FromGlib::from_glib(value) }),
|
||||||
}
|
|
||||||
Format::__Unknown(_) => Self::Other(format, value),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +115,7 @@ impl GenericFormattedValue {
|
||||||
Self::Time(v) => v.into_raw_value(),
|
Self::Time(v) => v.into_raw_value(),
|
||||||
Self::Buffers(v) => v.into_raw_value(),
|
Self::Buffers(v) => v.into_raw_value(),
|
||||||
Self::Percent(v) => v.into_raw_value(),
|
Self::Percent(v) => v.into_raw_value(),
|
||||||
Self::Other(_, v) => v,
|
Self::Other(_, v) => v.into_glib() as i64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +143,7 @@ impl FormattedValue for GenericFormattedValue {
|
||||||
Self::Time(v) => v.is_some(),
|
Self::Time(v) => v.is_some(),
|
||||||
Self::Buffers(v) => v.is_some(),
|
Self::Buffers(v) => v.is_some(),
|
||||||
Self::Percent(v) => v.is_some(),
|
Self::Percent(v) => v.is_some(),
|
||||||
Self::Other(..) => true,
|
Self::Other(_, v) => v.is_some(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +159,7 @@ impl FormattedValueFullRange for GenericFormattedValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormattedValueIntrinsic for GenericFormattedValue {}
|
impl FormattedValueIntrinsic for GenericFormattedValue {}
|
||||||
|
impl SignedIntrinsic for GenericFormattedValue {}
|
||||||
|
|
||||||
impl FormattedValueNoneBuilder for GenericFormattedValue {
|
impl FormattedValueNoneBuilder for GenericFormattedValue {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
@ -142,7 +180,7 @@ impl FormattedValueNoneBuilder for GenericFormattedValue {
|
||||||
Format::Time => Self::Time(None),
|
Format::Time => Self::Time(None),
|
||||||
Format::Buffers => Self::Buffers(None),
|
Format::Buffers => Self::Buffers(None),
|
||||||
Format::Percent => Self::Percent(None),
|
Format::Percent => Self::Percent(None),
|
||||||
Format::__Unknown(_) => panic!("`None` can't be represented by `__Unknown`"),
|
unknown => Self::Other(unknown, Other::NONE),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,27 +189,21 @@ impl UnsignedIntoSigned for GenericFormattedValue {
|
||||||
type Signed = Signed<GenericFormattedValue>;
|
type Signed = Signed<GenericFormattedValue>;
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn into_positive(self) -> Signed<GenericFormattedValue> {
|
fn into_positive(self) -> Self::Signed {
|
||||||
match self {
|
match self {
|
||||||
GenericFormattedValue::Undefined(_) => {
|
GenericFormattedValue::Undefined(_) => {
|
||||||
unimplemented!("`GenericFormattedValue::Undefined` is already signed")
|
unimplemented!("`GenericFormattedValue::Undefined` is already signed")
|
||||||
}
|
}
|
||||||
GenericFormattedValue::Other(..) => {
|
|
||||||
unimplemented!("`GenericFormattedValue::Other` is already signed")
|
|
||||||
}
|
|
||||||
unsigned_inner => Signed::Positive(unsigned_inner),
|
unsigned_inner => Signed::Positive(unsigned_inner),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn into_negative(self) -> Signed<GenericFormattedValue> {
|
fn into_negative(self) -> Self::Signed {
|
||||||
match self {
|
match self {
|
||||||
GenericFormattedValue::Undefined(_) => {
|
GenericFormattedValue::Undefined(_) => {
|
||||||
unimplemented!("`GenericFormattedValue::Undefined` is already signed")
|
unimplemented!("`GenericFormattedValue::Undefined` is already signed")
|
||||||
}
|
}
|
||||||
GenericFormattedValue::Other(..) => {
|
|
||||||
unimplemented!("`GenericFormattedValue::Other` is already signed")
|
|
||||||
}
|
|
||||||
unsigned_inner => Signed::Negative(unsigned_inner),
|
unsigned_inner => Signed::Negative(unsigned_inner),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,3 +232,56 @@ impl CompatibleFormattedValue<GenericFormattedValue> for GenericFormattedValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::eq_op, clippy::op_ref)]
|
||||||
|
fn other() {
|
||||||
|
// Check a few ops on `Other`, better converage for
|
||||||
|
// the macro ops impl ensured as part of the `clock_time` module.
|
||||||
|
|
||||||
|
use opt_ops::prelude::*;
|
||||||
|
|
||||||
|
let other_none: Option<Other> = Other::try_from(u64::MAX).ok();
|
||||||
|
assert!(other_none.is_none());
|
||||||
|
|
||||||
|
let other_10 = Other::try_from(10).unwrap();
|
||||||
|
let other_20 = Other::try_from(20).unwrap();
|
||||||
|
let other_30 = Other::try_from(30).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(other_10 + other_20, other_30);
|
||||||
|
assert_eq!(other_30 - other_20, other_10);
|
||||||
|
|
||||||
|
assert!(other_10 < Other::MAX);
|
||||||
|
|
||||||
|
assert_eq!(Some(other_10).opt_add(other_20), Some(other_30));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::eq_op, clippy::op_ref)]
|
||||||
|
fn generic_other() {
|
||||||
|
let gen_other_42: GenericFormattedValue =
|
||||||
|
GenericFormattedValue::new(Format::__Unknown(128), 42);
|
||||||
|
assert_eq!(
|
||||||
|
gen_other_42,
|
||||||
|
GenericFormattedValue::Other(Format::__Unknown(128), Some(Other(42)))
|
||||||
|
);
|
||||||
|
assert_eq!(gen_other_42.format(), Format::__Unknown(128));
|
||||||
|
assert_eq!(gen_other_42.value(), 42);
|
||||||
|
assert!(gen_other_42.is_some());
|
||||||
|
|
||||||
|
let other_none: Option<Other> = Other::NONE;
|
||||||
|
assert!(other_none.is_none());
|
||||||
|
|
||||||
|
let gen_other_none: GenericFormattedValue =
|
||||||
|
GenericFormattedValue::none_for_format(Format::__Unknown(128));
|
||||||
|
assert!(gen_other_none.is_none());
|
||||||
|
assert_eq!(
|
||||||
|
gen_other_none,
|
||||||
|
GenericFormattedValue::Other(Format::__Unknown(128), None)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -183,6 +183,8 @@ macro_rules! impl_non_trait_op_inner_type(
|
||||||
|
|
||||||
macro_rules! impl_unsigned_int_into_signed(
|
macro_rules! impl_unsigned_int_into_signed(
|
||||||
($typ:ty) => {
|
($typ:ty) => {
|
||||||
|
impl crate::format::SignedIntrinsic for $typ {}
|
||||||
|
|
||||||
impl crate::UnsignedIntoSigned for $typ {
|
impl crate::UnsignedIntoSigned for $typ {
|
||||||
type Signed = crate::Signed<$typ>;
|
type Signed = crate::Signed<$typ>;
|
||||||
|
|
||||||
|
@ -239,6 +241,20 @@ macro_rules! impl_common_ops_for_newtype_uint(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for $typ {
|
||||||
|
type Target = $inner;
|
||||||
|
|
||||||
|
fn deref(&self) -> &$inner {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<$inner> for $typ {
|
||||||
|
fn as_ref(&self) -> &$inner {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_trait_op_same!($typ, Add, add, AddAssign, add_assign);
|
impl_trait_op_same!($typ, Add, add, AddAssign, add_assign);
|
||||||
impl_trait_op_same!($typ, Sub, sub, SubAssign, sub_assign);
|
impl_trait_op_same!($typ, Sub, sub, SubAssign, sub_assign);
|
||||||
impl std::ops::Div for $typ {
|
impl std::ops::Div for $typ {
|
||||||
|
@ -1467,7 +1483,7 @@ macro_rules! impl_format_value_traits(
|
||||||
|
|
||||||
impl TryFrom<$inner> for $typ {
|
impl TryFrom<$inner> for $typ {
|
||||||
type Error = GlibNoneError;
|
type Error = GlibNoneError;
|
||||||
fn try_from(v: $inner) -> Result<$typ, GlibNoneError> {
|
fn try_from(v: $inner) -> Result<Self, GlibNoneError> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
unsafe { Self::try_from_glib(v as i64) }
|
unsafe { Self::try_from_glib(v as i64) }
|
||||||
}
|
}
|
||||||
|
@ -1481,32 +1497,6 @@ macro_rules! impl_format_value_traits(
|
||||||
<$typ as TryFromGlib<u64>>::try_from_glib(val as u64)
|
<$typ as TryFromGlib<u64>>::try_from_glib(val as u64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for $typ {
|
|
||||||
type Target = $inner;
|
|
||||||
|
|
||||||
fn deref(&self) -> &$inner {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::DerefMut for $typ {
|
|
||||||
fn deref_mut(&mut self) -> &mut $inner {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<$inner> for $typ {
|
|
||||||
fn as_ref(&self) -> &$inner {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsMut<$inner> for $typ {
|
|
||||||
fn as_mut(&mut self) -> &mut $inner {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1545,16 +1535,12 @@ macro_rules! option_glib_newtype_from_to {
|
||||||
// `$displayable_option_name` if `concat_idents!` was stable.
|
// `$displayable_option_name` if `concat_idents!` was stable.
|
||||||
// See: https://doc.rust-lang.org/std/macro.concat_idents.html
|
// See: https://doc.rust-lang.org/std/macro.concat_idents.html
|
||||||
macro_rules! glib_newtype_display {
|
macro_rules! glib_newtype_display {
|
||||||
($typ:ty, $displayable_name:ident, $unit:expr) => {
|
($typ:ty, $displayable_name:ident) => {
|
||||||
pub struct $displayable_name($typ);
|
pub struct $displayable_name($typ);
|
||||||
|
|
||||||
impl std::fmt::Display for $typ {
|
impl std::fmt::Display for $typ {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
use std::fmt::Write;
|
std::fmt::Display::fmt(&self.0, f)
|
||||||
|
|
||||||
std::fmt::Display::fmt(&self.0, f)?;
|
|
||||||
f.write_char(' ')?;
|
|
||||||
f.write_str($unit)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1566,8 +1552,50 @@ macro_rules! glib_newtype_display {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
($typ:ty, $displayable_name:ident, $displayable_option_name:ident, $unit:expr) => {
|
($typ:ty, $displayable_name:ident, Format::$format:ident$(,)?) => {
|
||||||
glib_newtype_display!($typ, $displayable_name, $unit);
|
pub struct $displayable_name($typ);
|
||||||
|
|
||||||
|
impl std::fmt::Display for $typ {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.0, f)?;
|
||||||
|
std::fmt::Write::write_char(f, ' ')?;
|
||||||
|
std::fmt::Display::fmt(&Format::$format, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::utils::Displayable for $typ {
|
||||||
|
type DisplayImpl = $typ;
|
||||||
|
fn display(self) -> $typ {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($typ:ty, $displayable_name:ident, $displayable_option_name:ident) => {
|
||||||
|
glib_newtype_display!($typ, $displayable_name);
|
||||||
|
|
||||||
|
pub struct $displayable_option_name(Option<$typ>);
|
||||||
|
|
||||||
|
impl std::fmt::Display for $displayable_option_name {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
if let Some(val) = self.0.as_ref() {
|
||||||
|
std::fmt::Display::fmt(val, f)
|
||||||
|
} else {
|
||||||
|
f.write_str("undef.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::utils::Displayable for Option<$typ> {
|
||||||
|
type DisplayImpl = $displayable_option_name;
|
||||||
|
fn display(self) -> Self::DisplayImpl {
|
||||||
|
$displayable_option_name(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($typ:ty, $displayable_name:ident, $displayable_option_name:ident, Format::$format:ident$(,)?) => {
|
||||||
|
glib_newtype_display!($typ, $displayable_name, Format::$format);
|
||||||
|
|
||||||
pub struct $displayable_option_name(Option<$typ>);
|
pub struct $displayable_option_name(Option<$typ>);
|
||||||
|
|
||||||
|
@ -1577,7 +1605,7 @@ macro_rules! glib_newtype_display {
|
||||||
std::fmt::Display::fmt(val, f)
|
std::fmt::Display::fmt(val, f)
|
||||||
} else {
|
} else {
|
||||||
f.write_str("undef. ")?;
|
f.write_str("undef. ")?;
|
||||||
f.write_str($unit)
|
std::fmt::Display::fmt(&Format::$format, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -522,6 +522,21 @@ pub trait FormattedValueNoneBuilder: FormattedValueFullRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
impl fmt::Display for Format {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Undefined => f.write_str("undefined"),
|
||||||
|
Self::Default => f.write_str("default"),
|
||||||
|
Self::Bytes => f.write_str("bytes"),
|
||||||
|
Self::Time => f.write_str("time"),
|
||||||
|
Self::Buffers => f.write_str("buffers"),
|
||||||
|
Self::Percent => f.write_str("%"),
|
||||||
|
Self::__Unknown(format) => write!(f, "(format: {})", format),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -715,6 +730,7 @@ mod tests {
|
||||||
assert_eq!(signed.positive(), Some(ct_1));
|
assert_eq!(signed.positive(), Some(ct_1));
|
||||||
assert!(!signed.is_negative());
|
assert!(!signed.is_negative());
|
||||||
assert!(signed.negative().is_none());
|
assert!(signed.negative().is_none());
|
||||||
|
assert_eq!(signed.signum(), 1);
|
||||||
|
|
||||||
let signed = ct_1.into_negative();
|
let signed = ct_1.into_negative();
|
||||||
assert_eq!(signed, Signed::Negative(ct_1));
|
assert_eq!(signed, Signed::Negative(ct_1));
|
||||||
|
@ -722,6 +738,7 @@ mod tests {
|
||||||
assert_eq!(signed.negative(), Some(ct_1));
|
assert_eq!(signed.negative(), Some(ct_1));
|
||||||
assert!(!signed.is_positive());
|
assert!(!signed.is_positive());
|
||||||
assert!(signed.positive().is_none());
|
assert!(signed.positive().is_none());
|
||||||
|
assert_eq!(signed.signum(), -1);
|
||||||
|
|
||||||
let def = Default(1);
|
let def = Default(1);
|
||||||
|
|
||||||
|
@ -731,6 +748,7 @@ mod tests {
|
||||||
assert_eq!(signed.positive(), Some(def));
|
assert_eq!(signed.positive(), Some(def));
|
||||||
assert!(!signed.is_negative());
|
assert!(!signed.is_negative());
|
||||||
assert!(signed.negative().is_none());
|
assert!(signed.negative().is_none());
|
||||||
|
assert_eq!(signed.signum(), 1);
|
||||||
|
|
||||||
let signed = def.into_negative();
|
let signed = def.into_negative();
|
||||||
assert_eq!(signed, Signed::Negative(def));
|
assert_eq!(signed, Signed::Negative(def));
|
||||||
|
@ -738,6 +756,17 @@ mod tests {
|
||||||
assert_eq!(signed.negative(), Some(def));
|
assert_eq!(signed.negative(), Some(def));
|
||||||
assert!(!signed.is_positive());
|
assert!(!signed.is_positive());
|
||||||
assert!(signed.positive().is_none());
|
assert!(signed.positive().is_none());
|
||||||
|
assert_eq!(signed.signum(), -1);
|
||||||
|
|
||||||
|
let ct_zero = ClockTime::ZERO;
|
||||||
|
let p_ct_zero = ct_zero.into_positive();
|
||||||
|
assert!(p_ct_zero.is_positive());
|
||||||
|
assert!(!p_ct_zero.is_negative());
|
||||||
|
assert_eq!(p_ct_zero.signum(), 0);
|
||||||
|
let n_ct_zero = ct_zero.into_negative();
|
||||||
|
assert!(n_ct_zero.is_negative());
|
||||||
|
assert!(!n_ct_zero.is_positive());
|
||||||
|
assert_eq!(n_ct_zero.signum(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -811,6 +840,20 @@ mod tests {
|
||||||
&format!("{}", GenericFormattedValue::Percent(None)),
|
&format!("{}", GenericFormattedValue::Percent(None)),
|
||||||
"undef. %"
|
"undef. %"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let other: Other = 42.try_into().unwrap();
|
||||||
|
assert_eq!(&format!("{other}"), "42");
|
||||||
|
|
||||||
|
let g_other = GenericFormattedValue::new(Format::__Unknown(128), 42);
|
||||||
|
assert_eq!(&format!("{g_other}"), "42 (format: 128)");
|
||||||
|
assert_eq!(&format!("{}", g_other.display()), "42 (format: 128)");
|
||||||
|
|
||||||
|
let g_other_none = GenericFormattedValue::Other(Format::__Unknown(128), None);
|
||||||
|
assert_eq!(&format!("{g_other_none}"), "undef. (format: 128)");
|
||||||
|
assert_eq!(
|
||||||
|
&format!("{}", g_other_none.display()),
|
||||||
|
"undef. (format: 128)"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -842,5 +885,21 @@ mod tests {
|
||||||
|
|
||||||
let none_s_bytes = Option::<Signed<Bytes>>::None;
|
let none_s_bytes = Option::<Signed<Bytes>>::None;
|
||||||
assert_eq!(&format!("{}", none_s_bytes.display()), "undef. bytes");
|
assert_eq!(&format!("{}", none_s_bytes.display()), "undef. bytes");
|
||||||
|
|
||||||
|
let ct_1 = 45_834_908_569_837 * ClockTime::NSECOND;
|
||||||
|
assert_eq!(&format!("{ct_1}"), "12:43:54.908569837");
|
||||||
|
assert_eq!(&format!("{}", ct_1.display()), "12:43:54.908569837");
|
||||||
|
|
||||||
|
let g_ct_1 = GenericFormattedValue::Time(Some(ct_1));
|
||||||
|
assert_eq!(&format!("{g_ct_1}"), "12:43:54.908569837");
|
||||||
|
assert_eq!(&format!("{}", g_ct_1.display()), "12:43:54.908569837");
|
||||||
|
|
||||||
|
let p_g_ct1 = g_ct_1.into_positive();
|
||||||
|
assert_eq!(&format!("{p_g_ct1}"), "+12:43:54.908569837");
|
||||||
|
assert_eq!(&format!("{}", p_g_ct1.display()), "+12:43:54.908569837");
|
||||||
|
|
||||||
|
let n_g_ct1 = g_ct_1.into_negative();
|
||||||
|
assert_eq!(&format!("{n_g_ct1}"), "-12:43:54.908569837");
|
||||||
|
assert_eq!(&format!("{}", n_g_ct1.display()), "-12:43:54.908569837");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use super::{Format, FormattedValueIntrinsic, FormattedValueNoneBuilder};
|
use super::{Format, FormattedValueNoneBuilder};
|
||||||
use crate::utils::Displayable;
|
use crate::utils::Displayable;
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
|
@ -12,7 +12,8 @@ use crate::utils::Displayable;
|
||||||
/// which is originaly unsigned. In C APIs, this is represented
|
/// which is originaly unsigned. In C APIs, this is represented
|
||||||
/// by a tuple with a signed integer positive or negative and
|
/// by a tuple with a signed integer positive or negative and
|
||||||
/// the absolute value.
|
/// the absolute value.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub enum Signed<T> {
|
pub enum Signed<T> {
|
||||||
Negative(T),
|
Negative(T),
|
||||||
Positive(T),
|
Positive(T),
|
||||||
|
@ -87,20 +88,6 @@ impl<T> Signed<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
|
||||||
/// Returns the multiplication factor for this `Signed`.
|
|
||||||
///
|
|
||||||
/// Returns:
|
|
||||||
///
|
|
||||||
/// - `1` if the value must be considered as positive.
|
|
||||||
/// - `-1` if the value must be considered as negative.
|
|
||||||
pub fn factor(self) -> i32 {
|
|
||||||
match self {
|
|
||||||
Signed::Positive(_) => 1i32,
|
|
||||||
Signed::Negative(_) => -1i32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Returns the absolute value of `self`.
|
/// Returns the absolute value of `self`.
|
||||||
pub fn abs(self) -> T {
|
pub fn abs(self) -> T {
|
||||||
|
@ -121,9 +108,11 @@ impl<T> std::ops::Neg for Signed<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait SignedIntrinsic {}
|
||||||
|
|
||||||
impl<T> fmt::Display for Signed<T>
|
impl<T> fmt::Display for Signed<T>
|
||||||
where
|
where
|
||||||
T: fmt::Display + FormattedValueIntrinsic,
|
T: fmt::Display + SignedIntrinsic,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
@ -140,7 +129,7 @@ where
|
||||||
|
|
||||||
impl<T> Displayable for Signed<T>
|
impl<T> Displayable for Signed<T>
|
||||||
where
|
where
|
||||||
T: fmt::Display + FormattedValueIntrinsic,
|
T: fmt::Display + SignedIntrinsic,
|
||||||
{
|
{
|
||||||
type DisplayImpl = Signed<T>;
|
type DisplayImpl = Signed<T>;
|
||||||
|
|
||||||
|
@ -169,7 +158,7 @@ pub struct DisplayableOptionSigned<T>(Option<Signed<T>>);
|
||||||
|
|
||||||
impl<T> fmt::Display for DisplayableOptionSigned<T>
|
impl<T> fmt::Display for DisplayableOptionSigned<T>
|
||||||
where
|
where
|
||||||
T: fmt::Display + FormattedValueIntrinsic,
|
T: fmt::Display + SignedIntrinsic,
|
||||||
Option<T>: Displayable,
|
Option<T>: Displayable,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
@ -182,7 +171,7 @@ where
|
||||||
|
|
||||||
impl<T> Displayable for Option<Signed<T>>
|
impl<T> Displayable for Option<Signed<T>>
|
||||||
where
|
where
|
||||||
T: fmt::Display + FormattedValueIntrinsic,
|
T: fmt::Display + SignedIntrinsic,
|
||||||
Option<T>: Displayable,
|
Option<T>: Displayable,
|
||||||
{
|
{
|
||||||
type DisplayImpl = DisplayableOptionSigned<T>;
|
type DisplayImpl = DisplayableOptionSigned<T>;
|
||||||
|
@ -194,7 +183,7 @@ where
|
||||||
|
|
||||||
impl<T> Displayable for Signed<Option<T>>
|
impl<T> Displayable for Signed<Option<T>>
|
||||||
where
|
where
|
||||||
T: fmt::Display + FormattedValueIntrinsic,
|
T: fmt::Display + SignedIntrinsic,
|
||||||
Option<T>: Displayable,
|
Option<T>: Displayable,
|
||||||
{
|
{
|
||||||
type DisplayImpl = DisplayableOptionSigned<T>;
|
type DisplayImpl = DisplayableOptionSigned<T>;
|
||||||
|
|
|
@ -36,7 +36,7 @@ glib_newtype_display!(
|
||||||
Buffers,
|
Buffers,
|
||||||
DisplayableBuffers,
|
DisplayableBuffers,
|
||||||
DisplayableOptionBuffers,
|
DisplayableOptionBuffers,
|
||||||
"buffers"
|
Format::Buffers,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
||||||
|
@ -49,7 +49,12 @@ impl_common_ops_for_newtype_uint!(Bytes, u64);
|
||||||
impl_signed_div_mul!(Bytes, u64);
|
impl_signed_div_mul!(Bytes, u64);
|
||||||
impl_format_value_traits!(Bytes, Bytes, Bytes, u64);
|
impl_format_value_traits!(Bytes, Bytes, Bytes, u64);
|
||||||
option_glib_newtype_from_to!(Bytes, u64::MAX);
|
option_glib_newtype_from_to!(Bytes, u64::MAX);
|
||||||
glib_newtype_display!(Bytes, DisplayableBytes, DisplayableOptionBytes, "bytes");
|
glib_newtype_display!(
|
||||||
|
Bytes,
|
||||||
|
DisplayableBytes,
|
||||||
|
DisplayableOptionBytes,
|
||||||
|
Format::Bytes,
|
||||||
|
);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
|
||||||
pub struct Default(pub u64);
|
pub struct Default(pub u64);
|
||||||
|
@ -65,7 +70,7 @@ glib_newtype_display!(
|
||||||
Default,
|
Default,
|
||||||
DisplayableDefault,
|
DisplayableDefault,
|
||||||
DisplayableOptionDefault,
|
DisplayableOptionDefault,
|
||||||
"(Default)"
|
Format::Default,
|
||||||
);
|
);
|
||||||
|
|
||||||
pub type Time = super::ClockTime;
|
pub type Time = super::ClockTime;
|
||||||
|
@ -81,7 +86,12 @@ impl Percent {
|
||||||
|
|
||||||
impl_common_ops_for_newtype_uint!(Percent, u32);
|
impl_common_ops_for_newtype_uint!(Percent, u32);
|
||||||
impl_signed_div_mul!(Percent, u32);
|
impl_signed_div_mul!(Percent, u32);
|
||||||
glib_newtype_display!(Percent, DisplayablePercent, DisplayableOptionPercent, "%");
|
glib_newtype_display!(
|
||||||
|
Percent,
|
||||||
|
DisplayablePercent,
|
||||||
|
DisplayableOptionPercent,
|
||||||
|
Format::Percent,
|
||||||
|
);
|
||||||
|
|
||||||
impl FormattedValue for Option<Percent> {
|
impl FormattedValue for Option<Percent> {
|
||||||
type FullRange = Option<Percent>;
|
type FullRange = Option<Percent>;
|
||||||
|
@ -202,32 +212,6 @@ impl FormattedValueNoneBuilder for Option<Percent> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for Percent {
|
|
||||||
type Target = u32;
|
|
||||||
|
|
||||||
fn deref(&self) -> &u32 {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::DerefMut for Percent {
|
|
||||||
fn deref_mut(&mut self) -> &mut u32 {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<u32> for Percent {
|
|
||||||
fn as_ref(&self) -> &u32 {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsMut<u32> for Percent {
|
|
||||||
fn as_mut(&mut self) -> &mut u32 {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
|
||||||
#[error("value out of range")]
|
#[error("value out of range")]
|
||||||
pub struct TryPercentFromFloatError(());
|
pub struct TryPercentFromFloatError(());
|
||||||
|
|
|
@ -108,4 +108,4 @@ impl From<Undefined> for Signed<u64> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glib_newtype_display!(Undefined, DisplayableUndefined, "(Undefined)");
|
glib_newtype_display!(Undefined, DisplayableUndefined, Format::Undefined);
|
||||||
|
|
Loading…
Reference in a new issue