gstreamer/
param_spec.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::ffi;
4use glib::{gobject_ffi, prelude::*, translate::*, ParamSpec};
5
6glib::wrapper! {
7    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
8    #[doc(alias = "GstParamSpecFraction")]
9    pub struct ParamSpecFraction(Shared<ffi::GstParamSpecFraction>);
10
11    match fn {
12        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec),
13        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
14        type_ => || ffi::gst_param_spec_fraction_get_type(),
15    }
16}
17
18unsafe impl Send for ParamSpecFraction {}
19unsafe impl Sync for ParamSpecFraction {}
20
21impl std::ops::Deref for ParamSpecFraction {
22    type Target = ParamSpec;
23
24    #[inline]
25    fn deref(&self) -> &Self::Target {
26        unsafe { &*(self as *const ParamSpecFraction as *const ParamSpec) }
27    }
28}
29
30unsafe impl ParamSpecType for ParamSpecFraction {}
31
32impl HasParamSpec for crate::Fraction {
33    type ParamSpec = ParamSpecFraction;
34
35    type SetValue = crate::Fraction;
36    type BuilderFn = for<'a> fn(&'a str) -> ParamSpecFractionBuilder<'a>;
37
38    fn param_spec_builder() -> Self::BuilderFn {
39        ParamSpecFraction::builder
40    }
41}
42
43#[doc(hidden)]
44impl FromGlibPtrFull<*mut gobject_ffi::GParamSpec> for ParamSpecFraction {
45    #[inline]
46    unsafe fn from_glib_full(ptr: *mut gobject_ffi::GParamSpec) -> Self {
47        from_glib_full(ptr as *mut ffi::GstParamSpecFraction)
48    }
49}
50
51impl ParamSpecFraction {
52    #[doc(alias = "gst_param_spec_fraction")]
53    pub fn builder(name: &str) -> ParamSpecFractionBuilder {
54        assert_initialized_main_thread!();
55        ParamSpecFractionBuilder::new(name)
56    }
57
58    unsafe fn new_unchecked<'a>(
59        name: &str,
60        nick: impl Into<Option<&'a str>>,
61        blurb: impl Into<Option<&'a str>>,
62        min: crate::Fraction,
63        max: crate::Fraction,
64        default: crate::Fraction,
65        flags: glib::ParamFlags,
66    ) -> glib::ParamSpec {
67        unsafe {
68            from_glib_none(ffi::gst_param_spec_fraction(
69                name.to_glib_none().0,
70                nick.into().to_glib_none().0,
71                blurb.into().to_glib_none().0,
72                min.numer(),
73                min.denom(),
74                max.numer(),
75                max.denom(),
76                default.numer(),
77                default.denom(),
78                flags.into_glib(),
79            ))
80        }
81    }
82
83    #[inline]
84    pub fn minimum(&self) -> crate::Fraction {
85        unsafe {
86            let ptr = self.as_ptr();
87
88            crate::Fraction::new((*ptr).min_num, (*ptr).min_den)
89        }
90    }
91
92    #[inline]
93    pub fn maximum(&self) -> crate::Fraction {
94        unsafe {
95            let ptr = self.as_ptr();
96
97            crate::Fraction::new((*ptr).max_num, (*ptr).max_den)
98        }
99    }
100
101    #[inline]
102    pub fn default_value(&self) -> crate::Fraction {
103        unsafe {
104            let ptr = self.as_ptr();
105
106            crate::Fraction::new((*ptr).def_num, (*ptr).def_den)
107        }
108    }
109
110    #[inline]
111    pub fn upcast(self) -> ParamSpec {
112        unsafe {
113            from_glib_full(
114                IntoGlibPtr::<*mut ffi::GstParamSpecFraction>::into_glib_ptr(self)
115                    as *mut gobject_ffi::GParamSpec,
116            )
117        }
118    }
119
120    #[inline]
121    pub fn upcast_ref(&self) -> &ParamSpec {
122        self
123    }
124}
125
126#[derive(Default)]
127#[must_use]
128pub struct ParamSpecFractionBuilder<'a> {
129    name: &'a str,
130    nick: Option<&'a str>,
131    blurb: Option<&'a str>,
132    flags: glib::ParamFlags,
133    minimum: Option<crate::Fraction>,
134    maximum: Option<crate::Fraction>,
135    default_value: Option<crate::Fraction>,
136}
137
138impl<'a> ParamSpecFractionBuilder<'a> {
139    fn new(name: &'a str) -> Self {
140        assert_initialized_main_thread!();
141        Self {
142            name,
143            ..Default::default()
144        }
145    }
146
147    // rustdoc-stripper-ignore-next
148    /// Default: `-i32::MAX/1`
149    pub fn minimum(mut self, minimum: crate::Fraction) -> Self {
150        self.minimum = Some(minimum);
151        self
152    }
153
154    // rustdoc-stripper-ignore-next
155    /// Default: `i32::MAX/1`
156    pub fn maximum(mut self, maximum: crate::Fraction) -> Self {
157        self.maximum = Some(maximum);
158        self
159    }
160
161    // rustdoc-stripper-ignore-next
162    /// Default: `0/1`
163    pub fn default_value(mut self, default_value: crate::Fraction) -> Self {
164        self.default_value = Some(default_value);
165        self
166    }
167
168    #[must_use]
169    pub fn build(self) -> ParamSpec {
170        unsafe {
171            ParamSpecFraction::new_unchecked(
172                self.name,
173                self.nick.unwrap_or(self.name),
174                self.blurb.unwrap_or(self.name),
175                self.minimum
176                    .unwrap_or_else(|| crate::Fraction::new(-i32::MAX, 1)),
177                self.maximum
178                    .unwrap_or_else(|| crate::Fraction::new(i32::MAX, 1)),
179                self.default_value
180                    .unwrap_or_else(|| crate::Fraction::new(0, 1)),
181                self.flags,
182            )
183        }
184    }
185}
186
187impl<'a> glib::prelude::ParamSpecBuilderExt<'a> for ParamSpecFractionBuilder<'a> {
188    fn set_nick(&mut self, nick: Option<&'a str>) {
189        self.nick = nick;
190    }
191    fn set_blurb(&mut self, blurb: Option<&'a str>) {
192        self.blurb = blurb;
193    }
194    fn set_flags(&mut self, flags: glib::ParamFlags) {
195        self.flags = flags;
196    }
197    fn current_flags(&self) -> glib::ParamFlags {
198        self.flags
199    }
200}
201
202glib::wrapper! {
203    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
204    #[doc(alias = "GstParamSpecArray")]
205    pub struct ParamSpecArray(Shared<ffi::GstParamSpecArray>);
206
207    match fn {
208        ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec),
209        unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec),
210        type_ => || ffi::gst_param_spec_array_get_type(),
211    }
212}
213
214unsafe impl Send for ParamSpecArray {}
215unsafe impl Sync for ParamSpecArray {}
216
217impl std::ops::Deref for ParamSpecArray {
218    type Target = ParamSpec;
219
220    #[inline]
221    fn deref(&self) -> &Self::Target {
222        unsafe { &*(self as *const ParamSpecArray as *const ParamSpec) }
223    }
224}
225
226unsafe impl ParamSpecType for ParamSpecArray {}
227
228impl HasParamSpec for crate::Array {
229    type ParamSpec = ParamSpecArray;
230
231    type SetValue = crate::Array;
232    type BuilderFn = for<'a> fn(&'a str) -> ParamSpecArrayBuilder<'a>;
233
234    fn param_spec_builder() -> Self::BuilderFn {
235        ParamSpecArray::builder
236    }
237}
238
239#[doc(hidden)]
240impl FromGlibPtrFull<*mut gobject_ffi::GParamSpec> for ParamSpecArray {
241    #[inline]
242    unsafe fn from_glib_full(ptr: *mut gobject_ffi::GParamSpec) -> Self {
243        from_glib_full(ptr as *mut ffi::GstParamSpecArray)
244    }
245}
246
247impl ParamSpecArray {
248    #[doc(alias = "gst_param_spec_array")]
249    pub fn builder(name: &str) -> ParamSpecArrayBuilder {
250        assert_initialized_main_thread!();
251        ParamSpecArrayBuilder::new(name)
252    }
253
254    unsafe fn new_unchecked<'a>(
255        name: &str,
256        nick: impl Into<Option<&'a str>>,
257        blurb: impl Into<Option<&'a str>>,
258        element_spec: Option<&glib::ParamSpec>,
259        flags: glib::ParamFlags,
260    ) -> glib::ParamSpec {
261        unsafe {
262            from_glib_none(ffi::gst_param_spec_array(
263                name.to_glib_none().0,
264                nick.into().to_glib_none().0,
265                blurb.into().to_glib_none().0,
266                element_spec.to_glib_none().0,
267                flags.into_glib(),
268            ))
269        }
270    }
271
272    #[inline]
273    pub fn element_spec(&self) -> Option<&ParamSpec> {
274        unsafe {
275            let ptr = self.as_ptr();
276
277            if (*ptr).element_spec.is_null() {
278                None
279            } else {
280                Some(
281                    &*(&(*ptr).element_spec as *const *mut glib::gobject_ffi::GParamSpec
282                        as *const glib::ParamSpec),
283                )
284            }
285        }
286    }
287
288    #[inline]
289    pub fn upcast(self) -> ParamSpec {
290        unsafe {
291            from_glib_full(
292                IntoGlibPtr::<*mut ffi::GstParamSpecArray>::into_glib_ptr(self)
293                    as *mut gobject_ffi::GParamSpec,
294            )
295        }
296    }
297
298    #[inline]
299    pub fn upcast_ref(&self) -> &ParamSpec {
300        self
301    }
302}
303
304#[derive(Default)]
305#[must_use]
306pub struct ParamSpecArrayBuilder<'a> {
307    name: &'a str,
308    nick: Option<&'a str>,
309    blurb: Option<&'a str>,
310    flags: glib::ParamFlags,
311    element_spec: Option<&'a glib::ParamSpec>,
312}
313
314impl<'a> ParamSpecArrayBuilder<'a> {
315    fn new(name: &'a str) -> Self {
316        assert_initialized_main_thread!();
317        Self {
318            name,
319            ..Default::default()
320        }
321    }
322
323    // rustdoc-stripper-ignore-next
324    /// Default: `None`
325    pub fn element_spec(mut self, element_spec: impl Into<Option<&'a glib::ParamSpec>>) -> Self {
326        self.element_spec = element_spec.into();
327        self
328    }
329
330    #[must_use]
331    pub fn build(self) -> ParamSpec {
332        unsafe {
333            ParamSpecArray::new_unchecked(
334                self.name,
335                self.nick.unwrap_or(self.name),
336                self.blurb.unwrap_or(self.name),
337                self.element_spec,
338                self.flags,
339            )
340        }
341    }
342}
343
344impl<'a> glib::prelude::ParamSpecBuilderExt<'a> for ParamSpecArrayBuilder<'a> {
345    fn set_nick(&mut self, nick: Option<&'a str>) {
346        self.nick = nick;
347    }
348    fn set_blurb(&mut self, blurb: Option<&'a str>) {
349        self.blurb = blurb;
350    }
351    fn set_flags(&mut self, flags: glib::ParamFlags) {
352        self.flags = flags;
353    }
354    fn current_flags(&self) -> glib::ParamFlags {
355        self.flags
356    }
357}
358
359pub trait GstParamSpecBuilderExt<'a>: glib::prelude::ParamSpecBuilderExt<'a> {
360    // rustdoc-stripper-ignore-next
361    /// Mark the property as controllable
362    fn controllable(self) -> Self {
363        let flags = self.current_flags() | crate::PARAM_FLAG_CONTROLLABLE;
364        self.flags(flags)
365    }
366
367    // rustdoc-stripper-ignore-next
368    /// Mark the property as mutable in ready state
369    fn mutable_ready(self) -> Self {
370        let flags = self.current_flags() | crate::PARAM_FLAG_MUTABLE_READY;
371        self.flags(flags)
372    }
373
374    // rustdoc-stripper-ignore-next
375    /// Mark the property as mutable in paused state
376    fn mutable_paused(self) -> Self {
377        let flags = self.current_flags() | crate::PARAM_FLAG_MUTABLE_PAUSED;
378        self.flags(flags)
379    }
380
381    // rustdoc-stripper-ignore-next
382    /// Mark the property as mutable in playing state
383    fn mutable_playing(self) -> Self {
384        let flags = self.current_flags() | crate::PARAM_FLAG_MUTABLE_PLAYING;
385        self.flags(flags)
386    }
387
388    #[cfg(feature = "v1_18")]
389    // rustdoc-stripper-ignore-next
390    /// Mark the property for showing the default value in the docs
391    fn doc_show_default(self) -> Self {
392        let flags = self.current_flags() | crate::PARAM_FLAG_DOC_SHOW_DEFAULT;
393        self.flags(flags)
394    }
395
396    #[cfg(feature = "v1_18")]
397    // rustdoc-stripper-ignore-next
398    /// Mark the property for being only conditionally available
399    fn conditionally_available(self) -> Self {
400        let flags = self.current_flags() | crate::PARAM_FLAG_CONDITIONALLY_AVAILABLE;
401        self.flags(flags)
402    }
403}
404
405impl<'a, T: glib::prelude::ParamSpecBuilderExt<'a>> GstParamSpecBuilderExt<'a> for T {}
406
407#[cfg(test)]
408mod tests {
409    use glib::prelude::*;
410
411    use super::*;
412
413    #[test]
414    fn test_trait() {
415        crate::init().unwrap();
416
417        let _pspec = ParamSpecFraction::builder("foo")
418            .nick("Foo")
419            .blurb("Foo Bar")
420            .minimum((0, 1).into())
421            .maximum((100, 1).into())
422            .default_value((1, 1).into())
423            .readwrite()
424            .mutable_playing()
425            .build();
426    }
427}