gstreamer: Update for optional glib::Value type refactoring

This commit is contained in:
Sebastian Dröge 2022-03-07 13:18:56 +02:00
parent 0f22eb7633
commit 1f7a0f29d9
2 changed files with 39 additions and 51 deletions

View file

@ -77,14 +77,14 @@ impl glib::value::ValueType for ClockTime {
type Type = Self; type Type = Self;
} }
pub struct ClockTimeValueTypeOrNoneChecker<T>(std::marker::PhantomData<T>); pub enum ClockTimeValueTypeOrNoneChecker {}
unsafe impl<T: StaticType> glib::value::ValueTypeChecker for ClockTimeValueTypeOrNoneChecker<T> { unsafe impl glib::value::ValueTypeChecker for ClockTimeValueTypeOrNoneChecker {
type Error = glib::value::ValueTypeMismatchOrNoneError; type Error = glib::value::ValueTypeMismatchOrNoneError<glib::value::ValueTypeMismatchError>;
fn check(value: &glib::Value) -> Result<(), Self::Error> { fn check(value: &glib::Value) -> Result<(), Self::Error> {
skip_assert_initialized!(); skip_assert_initialized!();
glib::value::GenericValueTypeChecker::<T>::check(value)?; glib::value::GenericValueTypeChecker::<ClockTime>::check(value)?;
let gct = unsafe { glib::gobject_ffi::g_value_get_uint64(value.to_glib_none().0) }; let gct = unsafe { glib::gobject_ffi::g_value_get_uint64(value.to_glib_none().0) };
if gct == ffi::GST_CLOCK_TIME_NONE { if gct == ffi::GST_CLOCK_TIME_NONE {
@ -96,7 +96,7 @@ unsafe impl<T: StaticType> glib::value::ValueTypeChecker for ClockTimeValueTypeO
} }
unsafe impl<'a> glib::value::FromValue<'a> for ClockTime { unsafe impl<'a> glib::value::FromValue<'a> for ClockTime {
type Checker = ClockTimeValueTypeOrNoneChecker<Self>; type Checker = ClockTimeValueTypeOrNoneChecker;
unsafe fn from_value(value: &glib::Value) -> ClockTime { unsafe fn from_value(value: &glib::Value) -> ClockTime {
skip_assert_initialized!(); skip_assert_initialized!();

View file

@ -15,50 +15,26 @@ use glib::value::{FromValue, SendValue, ToSendValue};
use glib::StaticType; use glib::StaticType;
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)] #[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
pub enum GetError { pub enum GetError<E: std::error::Error> {
#[error("GetError: Structure field with name {name} not found")] #[error("GetError: Structure field with name {name} not found")]
FieldNotFound { name: &'static str }, FieldNotFound { name: &'static str },
#[error("GetError: Structure field with name {name} not retrieved")] #[error("GetError: Structure field with name {name} not retrieved")]
ValueGetError { ValueGetError {
name: &'static str, name: &'static str,
#[source] #[source]
type_mismatch_error: glib::value::ValueTypeMismatchOrNoneError, error: E,
}, },
} }
impl GetError { impl<E: std::error::Error> GetError<E> {
fn new_field_not_found(name: &'static str) -> Self { fn new_field_not_found(name: &'static str) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
GetError::FieldNotFound { name } GetError::FieldNotFound { name }
} }
fn from_value_get_error<E: GlibValueError>(name: &'static str, err: E) -> Self { fn from_value_get_error(name: &'static str, error: E) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
E::from_value_error(name, err) GetError::ValueGetError { name, error }
}
}
pub trait GlibValueError: 'static {
fn from_value_error(name: &'static str, err: Self) -> GetError;
}
impl GlibValueError for glib::value::ValueTypeMismatchError {
fn from_value_error(name: &'static str, err: Self) -> GetError {
skip_assert_initialized!();
GetError::ValueGetError {
name,
type_mismatch_error: glib::value::ValueTypeMismatchOrNoneError::from(err),
}
}
}
impl GlibValueError for glib::value::ValueTypeMismatchOrNoneError {
fn from_value_error(name: &'static str, err: Self) -> GetError {
skip_assert_initialized!();
GetError::ValueGetError {
name,
type_mismatch_error: err,
}
} }
} }
@ -386,36 +362,45 @@ impl StructureRef {
} }
#[doc(alias = "gst_structure_get")] #[doc(alias = "gst_structure_get")]
pub fn get<'a, T: FromValue<'a>>(&'a self, name: &str) -> Result<T, GetError> pub fn get<'a, T: FromValue<'a>>(
where &'a self,
<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError, name: &str,
) -> Result<T, GetError<<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error>>
{ {
let name = glib::Quark::from_str(name); let name = glib::Quark::from_str(name);
self.get_by_quark(name) self.get_by_quark(name)
} }
#[doc(alias = "gst_structure_get")] #[doc(alias = "gst_structure_get")]
pub fn get_optional<'a, T: FromValue<'a>>(&'a self, name: &str) -> Result<Option<T>, GetError> pub fn get_optional<'a, T: FromValue<'a>>(
where &'a self,
<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError, name: &str,
{ ) -> Result<
Option<T>,
GetError<<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error>,
> {
let name = glib::Quark::from_str(name); let name = glib::Quark::from_str(name);
self.get_optional_by_quark(name) self.get_optional_by_quark(name)
} }
#[doc(alias = "get_value")] #[doc(alias = "get_value")]
#[doc(alias = "gst_structure_get_value")] #[doc(alias = "gst_structure_get_value")]
pub fn value(&self, name: &str) -> Result<&SendValue, GetError> { pub fn value(&self, name: &str) -> Result<&SendValue, GetError<std::convert::Infallible>> {
let name = glib::Quark::from_str(name); let name = glib::Quark::from_str(name);
self.value_by_quark(name) self.value_by_quark(name)
} }
#[doc(alias = "gst_structure_id_get")] #[doc(alias = "gst_structure_id_get")]
pub fn get_by_quark<'a, T: FromValue<'a>>(&'a self, name: glib::Quark) -> Result<T, GetError> pub fn get_by_quark<'a, T: FromValue<'a>>(
where &'a self,
<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError, name: glib::Quark,
) -> Result<T, GetError<<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error>>
{ {
self.value_by_quark(name)? self.value_by_quark(name)
.map_err(|err| match err {
GetError::FieldNotFound { name } => GetError::FieldNotFound { name },
_ => unreachable!(),
})?
.get() .get()
.map_err(|err| GetError::from_value_get_error(name.as_str(), err)) .map_err(|err| GetError::from_value_get_error(name.as_str(), err))
} }
@ -424,10 +409,10 @@ impl StructureRef {
pub fn get_optional_by_quark<'a, T: FromValue<'a>>( pub fn get_optional_by_quark<'a, T: FromValue<'a>>(
&'a self, &'a self,
name: glib::Quark, name: glib::Quark,
) -> Result<Option<T>, GetError> ) -> Result<
where Option<T>,
<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error: GlibValueError, GetError<<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error>,
{ > {
self.value_by_quark(name) self.value_by_quark(name)
.ok() .ok()
.map(|v| v.get()) .map(|v| v.get())
@ -436,7 +421,10 @@ impl StructureRef {
} }
#[doc(alias = "gst_structure_id_get_value")] #[doc(alias = "gst_structure_id_get_value")]
pub fn value_by_quark(&self, name: glib::Quark) -> Result<&SendValue, GetError> { pub fn value_by_quark(
&self,
name: glib::Quark,
) -> Result<&SendValue, GetError<std::convert::Infallible>> {
unsafe { unsafe {
let value = ffi::gst_structure_id_get_value(&self.0, name.into_glib()); let value = ffi::gst_structure_id_get_value(&self.0, name.into_glib());