From b901322c4642bd116eefeaaedd47350a71edc2de Mon Sep 17 00:00:00 2001 From: Fabian Orccon Date: Mon, 23 Oct 2023 23:39:41 +0200 Subject: [PATCH] gstreamer: rank: Do not implement gst::Rank as enum Rank is not limited to known types like GST_RANK_NONE, GST_RANK_MARGINAL, GST_RANK_SECONDARY and GST_RANK_PRIMARY, but it can be whatever arbitrary number. Part-of: --- .../src/subclass/formatter.rs | 2 +- gstreamer/Gir.toml | 10 +- gstreamer/src/auto/enums.rs | 105 ---------- gstreamer/src/auto/mod.rs | 1 - gstreamer/src/enums.rs | 59 ------ gstreamer/src/lib.rs | 2 + gstreamer/src/rank.rs | 197 ++++++++++++++++++ gstreamer/src/typefind.rs | 2 +- 8 files changed, 202 insertions(+), 176 deletions(-) create mode 100644 gstreamer/src/rank.rs diff --git a/gstreamer-editing-services/src/subclass/formatter.rs b/gstreamer-editing-services/src/subclass/formatter.rs index 47582723b..03cd9180b 100644 --- a/gstreamer-editing-services/src/subclass/formatter.rs +++ b/gstreamer-editing-services/src/subclass/formatter.rs @@ -336,7 +336,7 @@ mod tests { None, None, 1.0, - gst::Rank::Primary, + gst::Rank::PRIMARY, ); let proj = crate::Project::new(Some("ges:test:")); diff --git a/gstreamer/Gir.toml b/gstreamer/Gir.toml index 364506761..7dfb1e09a 100644 --- a/gstreamer/Gir.toml +++ b/gstreamer/Gir.toml @@ -58,6 +58,7 @@ manual = [ "Gst.DebugMessage", "Gst.DeviceProviderClass", # for docs only "Gst.ElementClass", # for docs only + "Gst.Rank", "Gst.Segment", "Gst.StaticCaps", "Gst.StaticPadTemplate", @@ -2058,15 +2059,6 @@ name = "Gst.Query" status = "manual" ref_mode = "ref" -[[object]] -name = "Gst.Rank" -status = "generate" - [[object.derive]] - name = "serde::Serialize, serde::Deserialize" - cfg_condition = "feature = \"serde\"" - [[object.derive]] - name = "Debug" - [[object]] name = "Gst.Registry" status = "generate" diff --git a/gstreamer/src/auto/enums.rs b/gstreamer/src/auto/enums.rs index 257db32f8..bbfc797a2 100644 --- a/gstreamer/src/auto/enums.rs +++ b/gstreamer/src/auto/enums.rs @@ -2430,111 +2430,6 @@ impl From for glib::Value { } } -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Debug, Clone, Copy)] -#[non_exhaustive] -#[doc(alias = "GstRank")] -pub enum Rank { - #[doc(alias = "GST_RANK_NONE")] - None, - #[doc(alias = "GST_RANK_MARGINAL")] - Marginal, - #[doc(alias = "GST_RANK_SECONDARY")] - Secondary, - #[doc(alias = "GST_RANK_PRIMARY")] - Primary, - #[doc(hidden)] - __Unknown(i32), -} - -#[doc(hidden)] -impl IntoGlib for Rank { - type GlibType = ffi::GstRank; - - #[inline] - fn into_glib(self) -> ffi::GstRank { - match self { - Self::None => ffi::GST_RANK_NONE, - Self::Marginal => ffi::GST_RANK_MARGINAL, - Self::Secondary => ffi::GST_RANK_SECONDARY, - Self::Primary => ffi::GST_RANK_PRIMARY, - Self::__Unknown(value) => value, - } - } -} - -#[doc(hidden)] -impl FromGlib for Rank { - #[inline] - unsafe fn from_glib(value: ffi::GstRank) -> Self { - skip_assert_initialized!(); - - match value { - ffi::GST_RANK_NONE => Self::None, - ffi::GST_RANK_MARGINAL => Self::Marginal, - ffi::GST_RANK_SECONDARY => Self::Secondary, - ffi::GST_RANK_PRIMARY => Self::Primary, - value => Self::__Unknown(value), - } - } -} - -impl StaticType for Rank { - #[inline] - #[doc(alias = "gst_rank_get_type")] - fn static_type() -> glib::Type { - unsafe { from_glib(ffi::gst_rank_get_type()) } - } -} - -impl glib::HasParamSpec for Rank { - type ParamSpec = glib::ParamSpecEnum; - type SetValue = Self; - type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; - - fn param_spec_builder() -> Self::BuilderFn { - Self::ParamSpec::builder_with_default - } -} - -impl glib::value::ValueType for Rank { - type Type = Self; -} - -unsafe impl<'a> glib::value::FromValue<'a> for Rank { - type Checker = glib::value::GenericValueTypeChecker; - - #[inline] - unsafe fn from_value(value: &'a glib::Value) -> Self { - skip_assert_initialized!(); - from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) - } -} - -impl ToValue for Rank { - #[inline] - fn to_value(&self) -> glib::Value { - let mut value = glib::Value::for_value_type::(); - unsafe { - glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); - } - value - } - - #[inline] - fn value_type(&self) -> glib::Type { - Self::static_type() - } -} - -impl From for glib::Value { - #[inline] - fn from(v: Rank) -> Self { - skip_assert_initialized!(); - ToValue::to_value(&v) - } -} - #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] #[non_exhaustive] #[doc(alias = "GstResourceError")] diff --git a/gstreamer/src/auto/mod.rs b/gstreamer/src/auto/mod.rs index e8eb15c62..6a4dc6e69 100644 --- a/gstreamer/src/auto/mod.rs +++ b/gstreamer/src/auto/mod.rs @@ -132,7 +132,6 @@ pub use self::enums::PluginError; pub use self::enums::ProgressType; pub use self::enums::PromiseResult; pub use self::enums::QOSType; -pub use self::enums::Rank; pub use self::enums::ResourceError; pub use self::enums::SeekType; pub use self::enums::State; diff --git a/gstreamer/src/enums.rs b/gstreamer/src/enums.rs index dbbcedd1f..88318e882 100644 --- a/gstreamer/src/enums.rs +++ b/gstreamer/src/enums.rs @@ -530,65 +530,6 @@ impl ops::SubAssign for crate::TypeFindProbability { } } -impl PartialEq for crate::Rank { - #[inline] - fn eq(&self, other: &crate::Rank) -> bool { - (self.into_glib() as u32).eq(&(other.into_glib() as u32)) - } -} - -impl Eq for crate::Rank {} - -impl PartialOrd for crate::Rank { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for crate::Rank { - #[inline] - fn cmp(&self, other: &Self) -> cmp::Ordering { - (self.into_glib() as u32).cmp(&(other.into_glib() as u32)) - } -} - -impl ops::Add for crate::Rank { - type Output = crate::Rank; - - #[inline] - fn add(self, rhs: u32) -> crate::Rank { - let res = (self.into_glib() as u32).saturating_add(rhs); - unsafe { from_glib(res as i32) } - } -} - -impl ops::AddAssign for crate::Rank { - #[inline] - fn add_assign(&mut self, rhs: u32) { - let res = (self.into_glib() as u32).saturating_add(rhs); - *self = unsafe { from_glib(res as i32) }; - } -} - -impl ops::Sub for crate::Rank { - type Output = crate::Rank; - - #[inline] - fn sub(self, rhs: u32) -> crate::Rank { - let res = (self.into_glib() as u32).saturating_sub(rhs); - unsafe { from_glib(res as i32) } - } -} - -impl ops::SubAssign for crate::Rank { - #[inline] - fn sub_assign(&mut self, rhs: u32) { - let res = (self.into_glib() as u32).saturating_sub(rhs); - *self = unsafe { from_glib(res as i32) }; - } -} - #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Error)] #[must_use] pub enum TagError { diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index 2a7e24748..4166c2c5a 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -134,6 +134,8 @@ pub mod event; pub use crate::event::{Event, EventRef, EventView, GroupId, Seqnum}; pub mod context; pub use crate::context::{Context, ContextRef}; +mod rank; +pub use crate::rank::Rank; mod static_caps; pub use crate::static_caps::*; mod static_pad_template; diff --git a/gstreamer/src/rank.rs b/gstreamer/src/rank.rs new file mode 100644 index 000000000..ea596a305 --- /dev/null +++ b/gstreamer/src/rank.rs @@ -0,0 +1,197 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use glib::{prelude::*, translate::*}; +use std::fmt; +use std::ops; + +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[doc(alias = "GstRank")] +pub struct Rank(i32); + +impl Rank { + #[doc(alias = "GST_RANK_NONE")] + pub const NONE: Rank = Self(ffi::GST_RANK_NONE); + #[doc(alias = "GST_RANK_MARGINAL")] + pub const MARGINAL: Rank = Self(ffi::GST_RANK_MARGINAL); + #[doc(alias = "GST_RANK_SECONDARY")] + pub const SECONDARY: Rank = Self(ffi::GST_RANK_SECONDARY); + #[doc(alias = "GST_RANK_PRIMARY")] + pub const PRIMARY: Rank = Self(ffi::GST_RANK_PRIMARY); +} + +impl IntoGlib for Rank { + type GlibType = i32; + + #[inline] + fn into_glib(self) -> i32 { + self.0 + } +} + +#[doc(hidden)] +impl FromGlib for Rank { + #[inline] + unsafe fn from_glib(value: i32) -> Self { + Rank(value) + } +} + +impl StaticType for Rank { + #[inline] + fn static_type() -> glib::Type { + unsafe { from_glib(ffi::gst_rank_get_type()) } + } +} + +impl glib::HasParamSpec for Rank { + type ParamSpec = glib::ParamSpecEnum; + type SetValue = Self; + type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder; + + fn param_spec_builder() -> Self::BuilderFn { + Self::ParamSpec::builder_with_default + } +} + +impl glib::value::ValueType for Rank { + type Type = Self; +} + +unsafe impl<'a> glib::value::FromValue<'a> for Rank { + type Checker = glib::value::GenericValueTypeChecker; + + #[inline] + unsafe fn from_value(value: &'a glib::Value) -> Self { + skip_assert_initialized!(); + from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) + } +} + +impl ToValue for Rank { + #[inline] + fn to_value(&self) -> glib::Value { + let mut value = glib::Value::for_value_type::(); + unsafe { + glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib()); + } + value + } + + #[inline] + fn value_type(&self) -> glib::Type { + Self::static_type() + } +} + +impl From for glib::Value { + #[inline] + fn from(v: Rank) -> Self { + skip_assert_initialized!(); + ToValue::to_value(&v) + } +} + +impl From for Rank { + #[inline] + fn from(v: i32) -> Self { + skip_assert_initialized!(); + Rank(v) + } +} + +impl From for i32 { + #[inline] + fn from(v: Rank) -> Self { + skip_assert_initialized!(); + v.0 + } +} + +impl ops::Add for Rank { + type Output = Rank; + + #[inline] + fn add(self, rhs: i32) -> Rank { + Rank(self.0 + rhs) + } +} + +impl ops::Add for i32 { + type Output = Rank; + + #[inline] + fn add(self, rhs: Rank) -> Rank { + Rank(self + rhs.0) + } +} + +impl ops::AddAssign for Rank { + #[inline] + fn add_assign(&mut self, rhs: i32) { + self.0 += rhs; + } +} + +impl ops::Sub for Rank { + type Output = Rank; + + #[inline] + fn sub(self, rhs: i32) -> Rank { + Rank(self.0 - rhs) + } +} + +impl ops::Sub for i32 { + type Output = Rank; + + #[inline] + fn sub(self, rhs: Rank) -> Rank { + Rank(self - rhs.0) + } +} + +impl ops::SubAssign for Rank { + #[inline] + fn sub_assign(&mut self, rhs: i32) { + self.0 -= rhs + } +} + +impl std::cmp::PartialEq for Rank { + #[inline] + fn eq(&self, rhs: &i32) -> bool { + self.0 == *rhs + } +} + +impl std::cmp::PartialEq for i32 { + #[inline] + fn eq(&self, rhs: &Rank) -> bool { + *self == rhs.0 + } +} + +impl fmt::Display for Rank { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let rank = self.into_glib(); + let names: [&str; 4] = ["none", "marginal", "secondary", "primary"]; + let ranks: [Rank; 4] = [Rank::NONE, Rank::MARGINAL, Rank::SECONDARY, Rank::PRIMARY]; + + let mut best_i = 0; + for i in 0..4 { + if rank == ranks[i].into_glib() { + return f.write_str(names[i]); + } + if (rank - ranks[i]).into_glib().abs() < (rank - ranks[best_i]).into_glib().abs() { + best_i = i; + } + } + + let diff = (rank - ranks[best_i]).into_glib(); + let op_str = if diff > 0 { '+' } else { '-' }; + + write!(f, "{} {} {}", names[best_i], op_str, diff.abs()) + } +} diff --git a/gstreamer/src/typefind.rs b/gstreamer/src/typefind.rs index d578d17ff..4a5acbcf7 100644 --- a/gstreamer/src/typefind.rs +++ b/gstreamer/src/typefind.rs @@ -281,7 +281,7 @@ mod tests { TypeFind::register( None, "test_typefind", - crate::Rank::Primary, + crate::Rank::PRIMARY, None, Some(&Caps::builder("test/test").build()), |typefind| {