mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-12-23 08:36:31 +00:00
gst/Segment: return immediately from some functions...
... if the input `is_none`.
This commit is contained in:
parent
8595b67218
commit
86549dc06e
4 changed files with 313 additions and 104 deletions
|
@ -439,6 +439,16 @@ pub trait FormattedValue: Copy + Clone + Sized + Into<GenericFormattedValue> + '
|
|||
#[doc(alias = "get_format")]
|
||||
fn format(&self) -> Format;
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Returns `true` if this `FormattedValue` represents a defined value.
|
||||
fn is_some(&self) -> bool;
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Returns `true` if this `FormattedValue` represents an undefined value.
|
||||
fn is_none(&self) -> bool {
|
||||
!self.is_some()
|
||||
}
|
||||
|
||||
unsafe fn into_raw_value(self) -> i64;
|
||||
}
|
||||
|
||||
|
@ -477,6 +487,87 @@ pub trait SpecificFormattedValueFullRange: FormattedValueFullRange {}
|
|||
/// - `Bytes` is the intrinsic type for `Option<Bytes>`.
|
||||
pub trait SpecificFormattedValueIntrinsic: TryFromGlib<i64> + FormattedValueIntrinsic {}
|
||||
|
||||
pub trait FormattedValueNoneBuilder: FormattedValueFullRange {
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Returns the `None` value for `Self` as a `FullRange` if such a value can be represented.
|
||||
///
|
||||
/// - For `SpecificFormattedValue`s, this results in `Option::<FormattedValueIntrinsic>::None`.
|
||||
/// - For `GenericFormattedValue`, this can only be obtained using [`Self::none_for_format`]
|
||||
/// because the `None` is an inner value of some of the variants.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `Self` is `GenericFormattedValue` in which case, the `Format` must be known.
|
||||
fn none() -> Self;
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Returns the `None` value for `Self` if such a value can be represented.
|
||||
///
|
||||
/// - For `SpecificFormattedValue`s, this is the same as `Self::none()`
|
||||
/// if the `format` matches the `SpecificFormattedValue`'s format.
|
||||
/// - For `GenericFormattedValue` this is the variant for the specified `format`,
|
||||
/// initialized with `None` as a value, if the `format` can represent that value.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `None` can't be represented by `Self` for `format` or by the requested
|
||||
/// `GenericFormattedValue` variant.
|
||||
#[track_caller]
|
||||
fn none_for_format(format: Format) -> Self {
|
||||
skip_assert_initialized!();
|
||||
// This is the default impl. `GenericFormattedValue` must override.
|
||||
if Self::default_format() != format {
|
||||
panic!(
|
||||
"Expected: {:?}, requested {format:?}",
|
||||
Self::default_format()
|
||||
);
|
||||
}
|
||||
|
||||
Self::none()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NoneSignedBuilder: FormattedValueNoneBuilder {
|
||||
type Signed;
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Returns the `None` value for `Self` as a `Signed<FullRange>` if such a value can be represented.
|
||||
///
|
||||
/// See details in [`FormattedValueNoneBuilder::none`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `Self` is `GenericFormattedValue` in which case, the `Format` must be known.
|
||||
fn none_signed() -> Self::Signed;
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Returns the `None` value for `Self` as a `Signed<FullRange>`, if such a value can be represented.
|
||||
///
|
||||
/// See details in [`FormattedValueNoneBuilder::none_for_format`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `None` can't be represented by `Self` for `format` or by the requested
|
||||
/// `GenericFormattedValue` variant.
|
||||
fn none_signed_for_format(format: Format) -> Self::Signed;
|
||||
}
|
||||
|
||||
impl<T> NoneSignedBuilder for T
|
||||
where
|
||||
T: UnsignedIntoSigned + FormattedValueNoneBuilder,
|
||||
{
|
||||
type Signed = <T as UnsignedIntoSigned>::Signed;
|
||||
|
||||
fn none_signed() -> Self::Signed {
|
||||
Self::none().into_positive()
|
||||
}
|
||||
|
||||
fn none_signed_for_format(format: Format) -> Self::Signed {
|
||||
skip_assert_initialized!();
|
||||
Self::none_for_format(format).into_positive()
|
||||
}
|
||||
}
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// A trait implemented on types which can hold [`FormattedValue`]s compatible with parameter `F`.
|
||||
///
|
||||
|
@ -686,6 +777,18 @@ impl FormattedValue for GenericFormattedValue {
|
|||
self.format()
|
||||
}
|
||||
|
||||
fn is_some(&self) -> bool {
|
||||
match self {
|
||||
Self::Undefined(_) => true,
|
||||
Self::Default(v) => v.is_some(),
|
||||
Self::Bytes(v) => v.is_some(),
|
||||
Self::Time(v) => v.is_some(),
|
||||
Self::Buffers(v) => v.is_some(),
|
||||
Self::Percent(v) => v.is_some(),
|
||||
Self::Other(..) => true,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn into_raw_value(self) -> i64 {
|
||||
self.value()
|
||||
}
|
||||
|
@ -697,6 +800,30 @@ impl FormattedValueFullRange for GenericFormattedValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl FormattedValueNoneBuilder for GenericFormattedValue {
|
||||
#[track_caller]
|
||||
fn none() -> Self {
|
||||
panic!(concat!(
|
||||
"`GenericFormattedValue` can't build `None` without knowing",
|
||||
"the target format. Use `GenericFormattedValue::none_for_format`",
|
||||
));
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn none_for_format(format: Format) -> Self {
|
||||
skip_assert_initialized!();
|
||||
match format {
|
||||
Format::Undefined => panic!("`None` can't be represented by `Undefined`"),
|
||||
Format::Default => Self::Default(None),
|
||||
Format::Bytes => Self::Bytes(None),
|
||||
Format::Time => Self::Time(None),
|
||||
Format::Buffers => Self::Buffers(None),
|
||||
Format::Percent => Self::Percent(None),
|
||||
Format::__Unknown(_) => panic!("`None` can't be represented by `__Unknown`"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GenericFormattedValue {
|
||||
pub fn new(format: Format, value: i64) -> Self {
|
||||
skip_assert_initialized!();
|
||||
|
@ -740,30 +867,6 @@ impl GenericFormattedValue {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_some(&self) -> bool {
|
||||
match *self {
|
||||
Self::Undefined(_) => true,
|
||||
Self::Default(v) => v.is_some(),
|
||||
Self::Bytes(v) => v.is_some(),
|
||||
Self::Time(v) => v.is_some(),
|
||||
Self::Buffers(v) => v.is_some(),
|
||||
Self::Percent(v) => v.is_some(),
|
||||
Self::Other(..) => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_none(&self) -> bool {
|
||||
match *self {
|
||||
Self::Undefined(_) => false,
|
||||
Self::Default(v) => v.is_none(),
|
||||
Self::Bytes(v) => v.is_none(),
|
||||
Self::Time(v) => v.is_none(),
|
||||
Self::Buffers(v) => v.is_none(),
|
||||
Self::Percent(v) => v.is_none(),
|
||||
Self::Other(..) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FormattedValueIntrinsic for GenericFormattedValue {}
|
||||
|
@ -839,6 +942,10 @@ impl FormattedValue for Undefined {
|
|||
Format::Undefined
|
||||
}
|
||||
|
||||
fn is_some(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
unsafe fn into_raw_value(self) -> i64 {
|
||||
self.0
|
||||
}
|
||||
|
@ -939,6 +1046,10 @@ impl FormattedValue for Option<Percent> {
|
|||
Format::Percent
|
||||
}
|
||||
|
||||
fn is_some(&self) -> bool {
|
||||
Option::is_some(self)
|
||||
}
|
||||
|
||||
unsafe fn into_raw_value(self) -> i64 {
|
||||
self.map_or(-1, |v| v.0 as i64)
|
||||
}
|
||||
|
@ -976,6 +1087,10 @@ impl FormattedValue for Percent {
|
|||
Format::Percent
|
||||
}
|
||||
|
||||
fn is_some(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
unsafe fn into_raw_value(self) -> i64 {
|
||||
self.0 as i64
|
||||
}
|
||||
|
@ -1033,6 +1148,11 @@ impl FormattedValueIntrinsic for Percent {}
|
|||
impl SpecificFormattedValue for Option<Percent> {}
|
||||
impl SpecificFormattedValueFullRange for Option<Percent> {}
|
||||
impl SpecificFormattedValueIntrinsic for Percent {}
|
||||
impl FormattedValueNoneBuilder for Option<Percent> {
|
||||
fn none() -> Option<Percent> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Deref for Percent {
|
||||
type Target = u32;
|
||||
|
@ -1204,6 +1324,48 @@ mod tests {
|
|||
.unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn none_builder() {
|
||||
let ct_none: Option<ClockTime> = Option::<ClockTime>::none();
|
||||
assert!(ct_none.is_none());
|
||||
|
||||
let ct_none: Option<ClockTime> = Option::<ClockTime>::none_for_format(Format::Time);
|
||||
assert!(ct_none.is_none());
|
||||
|
||||
let gen_ct_none: GenericFormattedValue =
|
||||
GenericFormattedValue::none_for_format(Format::Time);
|
||||
assert!(gen_ct_none.is_none());
|
||||
|
||||
assert!(ClockTime::ZERO.is_some());
|
||||
assert!(!ClockTime::ZERO.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn none_for_inconsistent_format() {
|
||||
let _ = Option::<ClockTime>::none_for_format(Format::Percent);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn none_for_unsupported_format() {
|
||||
let _ = GenericFormattedValue::none_for_format(Format::Undefined);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn none_signed_builder() {
|
||||
let ct_none: Option<Signed<ClockTime>> = Option::<ClockTime>::none_signed();
|
||||
assert!(ct_none.is_none());
|
||||
|
||||
let ct_none: Option<Signed<ClockTime>> =
|
||||
Option::<ClockTime>::none_signed_for_format(Format::Time);
|
||||
assert!(ct_none.is_none());
|
||||
|
||||
let gen_ct_none: Signed<GenericFormattedValue> =
|
||||
GenericFormattedValue::none_signed_for_format(Format::Time);
|
||||
assert!(gen_ct_none.abs().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn signed_optional() {
|
||||
let ct_1 = Some(ClockTime::SECOND);
|
||||
|
|
|
@ -227,8 +227,9 @@ mod typefind_factory;
|
|||
pub mod format;
|
||||
pub use crate::format::{
|
||||
CompatibleFormattedValue, FormattedValue, FormattedValueFullRange, FormattedValueIntrinsic,
|
||||
GenericFormattedValue, Signed, SpecificFormattedValue, SpecificFormattedValueFullRange,
|
||||
SpecificFormattedValueIntrinsic, UnsignedIntoSigned,
|
||||
FormattedValueNoneBuilder, GenericFormattedValue, NoneSignedBuilder, Signed,
|
||||
SpecificFormattedValue, SpecificFormattedValueFullRange, SpecificFormattedValueIntrinsic,
|
||||
UnsignedIntoSigned,
|
||||
};
|
||||
#[cfg(feature = "serde")]
|
||||
mod format_serde;
|
||||
|
@ -353,8 +354,8 @@ pub mod prelude {
|
|||
|
||||
pub use crate::format::{
|
||||
CompatibleFormattedValue, FormattedValue, FormattedValueFullRange, FormattedValueIntrinsic,
|
||||
SpecificFormattedValue, SpecificFormattedValueFullRange, SpecificFormattedValueIntrinsic,
|
||||
UnsignedIntoSigned,
|
||||
FormattedValueNoneBuilder, NoneSignedBuilder, SpecificFormattedValue,
|
||||
SpecificFormattedValueFullRange, SpecificFormattedValueIntrinsic, UnsignedIntoSigned,
|
||||
};
|
||||
pub use crate::utils::Displayable;
|
||||
|
||||
|
|
|
@ -1140,6 +1140,10 @@ macro_rules! impl_format_value_traits(
|
|||
Format::$format
|
||||
}
|
||||
|
||||
fn is_some(&self) -> bool {
|
||||
Option::is_some(self)
|
||||
}
|
||||
|
||||
unsafe fn into_raw_value(self) -> i64 {
|
||||
IntoGlib::into_glib(self) as i64
|
||||
}
|
||||
|
@ -1152,6 +1156,12 @@ macro_rules! impl_format_value_traits(
|
|||
}
|
||||
}
|
||||
|
||||
impl FormattedValueNoneBuilder for Option<$name> {
|
||||
fn none() -> Option<$name> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<$name>> for GenericFormattedValue {
|
||||
fn from(v: Option<$name>) -> Self {
|
||||
skip_assert_initialized!();
|
||||
|
@ -1165,6 +1175,7 @@ macro_rules! impl_format_value_traits(
|
|||
Self::$format_value(Some(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl FormattedValue for $name {
|
||||
type FullRange = Option<$name>;
|
||||
|
||||
|
@ -1176,6 +1187,10 @@ macro_rules! impl_format_value_traits(
|
|||
Format::$format
|
||||
}
|
||||
|
||||
fn is_some(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
unsafe fn into_raw_value(self) -> i64 {
|
||||
IntoGlib::into_glib(self) as i64
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::SeekFlags;
|
|||
use crate::SeekType;
|
||||
use crate::{
|
||||
CompatibleFormattedValue, FormattedValue, FormattedValueFullRange, FormattedValueIntrinsic,
|
||||
UnsignedIntoSigned,
|
||||
FormattedValueNoneBuilder, NoneSignedBuilder, UnsignedIntoSigned,
|
||||
};
|
||||
use glib::translate::*;
|
||||
use glib::StaticType;
|
||||
|
@ -175,48 +175,6 @@ impl<T: FormattedValueIntrinsic> FormattedSegment<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_segment_position_from_running_time")]
|
||||
pub fn position_from_running_time(
|
||||
&self,
|
||||
running_time: impl CompatibleFormattedValue<T>,
|
||||
) -> T::FullRange {
|
||||
let running_time = running_time
|
||||
.try_into_checked_explicit(self.format())
|
||||
.unwrap();
|
||||
|
||||
unsafe {
|
||||
T::FullRange::from_raw(
|
||||
self.format(),
|
||||
ffi::gst_segment_position_from_running_time(
|
||||
&self.0,
|
||||
self.format().into_glib(),
|
||||
running_time.into_raw_value() as u64,
|
||||
) as i64,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_segment_position_from_stream_time")]
|
||||
pub fn position_from_stream_time(
|
||||
&self,
|
||||
stream_time: impl CompatibleFormattedValue<T>,
|
||||
) -> T::FullRange {
|
||||
let stream_time = stream_time
|
||||
.try_into_checked_explicit(self.format())
|
||||
.unwrap();
|
||||
|
||||
unsafe {
|
||||
T::FullRange::from_raw(
|
||||
self.format(),
|
||||
ffi::gst_segment_position_from_stream_time(
|
||||
&self.0,
|
||||
self.format().into_glib(),
|
||||
stream_time.into_raw_value() as u64,
|
||||
) as i64,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_segment_set_running_time")]
|
||||
pub fn set_running_time(
|
||||
&mut self,
|
||||
|
@ -238,38 +196,6 @@ impl<T: FormattedValueIntrinsic> FormattedSegment<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_segment_to_running_time")]
|
||||
pub fn to_running_time(&self, position: impl CompatibleFormattedValue<T>) -> T::FullRange {
|
||||
let position = position.try_into_checked_explicit(self.format()).unwrap();
|
||||
|
||||
unsafe {
|
||||
T::FullRange::from_raw(
|
||||
self.format(),
|
||||
ffi::gst_segment_to_running_time(
|
||||
&self.0,
|
||||
self.format().into_glib(),
|
||||
position.into_raw_value() as u64,
|
||||
) as i64,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_segment_to_stream_time")]
|
||||
pub fn to_stream_time(&self, position: impl CompatibleFormattedValue<T>) -> T::FullRange {
|
||||
let position = position.try_into_checked_explicit(self.format()).unwrap();
|
||||
|
||||
unsafe {
|
||||
T::FullRange::from_raw(
|
||||
self.format(),
|
||||
ffi::gst_segment_to_stream_time(
|
||||
&self.0,
|
||||
self.format().into_glib(),
|
||||
position.into_raw_value() as u64,
|
||||
) as i64,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "get_flags")]
|
||||
pub fn flags(&self) -> crate::SegmentFlags {
|
||||
unsafe { from_glib(self.0.flags) }
|
||||
|
@ -388,7 +314,100 @@ impl<T: FormattedValueIntrinsic> PartialEq for FormattedSegment<T> {
|
|||
impl<T> FormattedSegment<T>
|
||||
where
|
||||
T: FormattedValueIntrinsic,
|
||||
<T as FormattedValue>::FullRange: UnsignedIntoSigned,
|
||||
T::FullRange: FormattedValueNoneBuilder,
|
||||
{
|
||||
#[doc(alias = "gst_segment_position_from_running_time")]
|
||||
pub fn position_from_running_time(
|
||||
&self,
|
||||
running_time: impl CompatibleFormattedValue<T>,
|
||||
) -> T::FullRange {
|
||||
let running_time = running_time
|
||||
.try_into_checked_explicit(self.format())
|
||||
.unwrap();
|
||||
if running_time.is_none() {
|
||||
return T::FullRange::none_for_format(self.format());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
T::FullRange::from_raw(
|
||||
self.format(),
|
||||
ffi::gst_segment_position_from_running_time(
|
||||
&self.0,
|
||||
self.format().into_glib(),
|
||||
running_time.into_raw_value() as u64,
|
||||
) as i64,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_segment_position_from_stream_time")]
|
||||
pub fn position_from_stream_time(
|
||||
&self,
|
||||
stream_time: impl CompatibleFormattedValue<T>,
|
||||
) -> T::FullRange {
|
||||
let stream_time = stream_time
|
||||
.try_into_checked_explicit(self.format())
|
||||
.unwrap();
|
||||
if stream_time.is_none() {
|
||||
return T::FullRange::none_for_format(self.format());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
T::FullRange::from_raw(
|
||||
self.format(),
|
||||
ffi::gst_segment_position_from_stream_time(
|
||||
&self.0,
|
||||
self.format().into_glib(),
|
||||
stream_time.into_raw_value() as u64,
|
||||
) as i64,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_segment_to_running_time")]
|
||||
pub fn to_running_time(&self, position: impl CompatibleFormattedValue<T>) -> T::FullRange {
|
||||
let position = position.try_into_checked_explicit(self.format()).unwrap();
|
||||
if position.is_none() {
|
||||
return T::FullRange::none_for_format(self.format());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
T::FullRange::from_raw(
|
||||
self.format(),
|
||||
ffi::gst_segment_to_running_time(
|
||||
&self.0,
|
||||
self.format().into_glib(),
|
||||
position.into_raw_value() as u64,
|
||||
) as i64,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_segment_to_stream_time")]
|
||||
pub fn to_stream_time(&self, position: impl CompatibleFormattedValue<T>) -> T::FullRange {
|
||||
let position = position.try_into_checked_explicit(self.format()).unwrap();
|
||||
if position.is_none() {
|
||||
return T::FullRange::none_for_format(self.format());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
T::FullRange::from_raw(
|
||||
self.format(),
|
||||
ffi::gst_segment_to_stream_time(
|
||||
&self.0,
|
||||
self.format().into_glib(),
|
||||
position.into_raw_value() as u64,
|
||||
) as i64,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FormattedSegment<T>
|
||||
where
|
||||
T: FormattedValueIntrinsic,
|
||||
T::FullRange: UnsignedIntoSigned,
|
||||
T::FullRange: NoneSignedBuilder<Signed = <T::FullRange as UnsignedIntoSigned>::Signed>,
|
||||
{
|
||||
#[doc(alias = "gst_segment_position_from_running_time_full")]
|
||||
pub fn position_from_running_time_full(
|
||||
|
@ -398,6 +417,9 @@ where
|
|||
let running_time = running_time
|
||||
.try_into_checked_explicit(self.format())
|
||||
.unwrap();
|
||||
if running_time.is_none() {
|
||||
return T::FullRange::none_signed_for_format(self.format());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut position = mem::MaybeUninit::uninit();
|
||||
|
@ -420,6 +442,9 @@ where
|
|||
let stream_time = stream_time
|
||||
.try_into_checked_explicit(self.format())
|
||||
.unwrap();
|
||||
if stream_time.is_none() {
|
||||
return T::FullRange::none_signed_for_format(self.format());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut position = mem::MaybeUninit::uninit();
|
||||
|
@ -440,6 +465,9 @@ where
|
|||
position: impl CompatibleFormattedValue<T>,
|
||||
) -> <T::FullRange as UnsignedIntoSigned>::Signed {
|
||||
let position = position.try_into_checked_explicit(self.format()).unwrap();
|
||||
if position.is_none() {
|
||||
return T::FullRange::none_signed_for_format(self.format());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut running_time = mem::MaybeUninit::uninit();
|
||||
|
@ -461,6 +489,9 @@ where
|
|||
position: impl CompatibleFormattedValue<T>,
|
||||
) -> <T::FullRange as UnsignedIntoSigned>::Signed {
|
||||
let position = position.try_into_checked_explicit(self.format()).unwrap();
|
||||
if position.is_none() {
|
||||
return T::FullRange::none_signed_for_format(self.format());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mut stream_time = mem::MaybeUninit::uninit();
|
||||
|
|
Loading…
Reference in a new issue