gstreamer/
query.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{
4    borrow::{Borrow, BorrowMut},
5    ffi::CStr,
6    fmt, mem,
7    ops::{Deref, DerefMut},
8    ptr,
9};
10
11use glib::{object::IsA, translate::*};
12use smallvec::SmallVec;
13
14use crate::{
15    ffi,
16    format::{CompatibleFormattedValue, FormattedValue, GenericFormattedValue},
17    structure::*,
18    QueryType,
19};
20
21mini_object_wrapper!(Query, QueryRef, ffi::GstQuery, || {
22    ffi::gst_query_get_type()
23});
24
25impl QueryType {
26    #[doc(alias = "GST_QUERY_IS_UPSTREAM")]
27    #[inline]
28    pub fn is_upstream(self) -> bool {
29        (self.into_glib() as u32) & ffi::GST_QUERY_TYPE_UPSTREAM != 0
30    }
31
32    #[doc(alias = "GST_QUERY_IS_DOWNSTREAM")]
33    #[inline]
34    pub fn is_downstream(self) -> bool {
35        (self.into_glib() as u32) & ffi::GST_QUERY_TYPE_DOWNSTREAM != 0
36    }
37
38    #[doc(alias = "GST_QUERY_IS_SERIALIZED")]
39    #[inline]
40    pub fn is_serialized(self) -> bool {
41        (self.into_glib() as u32) & ffi::GST_QUERY_TYPE_SERIALIZED != 0
42    }
43}
44
45impl QueryRef {
46    #[doc(alias = "get_structure")]
47    #[doc(alias = "gst_query_get_structure")]
48    #[inline]
49    pub fn structure(&self) -> Option<&StructureRef> {
50        unsafe {
51            let structure = ffi::gst_query_get_structure(self.as_mut_ptr());
52            if structure.is_null() {
53                None
54            } else {
55                Some(StructureRef::from_glib_borrow(structure))
56            }
57        }
58    }
59
60    #[doc(alias = "get_mut_structure")]
61    #[doc(alias = "gst_query_writable_structure")]
62    #[inline]
63    pub fn structure_mut(&mut self) -> &mut StructureRef {
64        unsafe {
65            let structure = ffi::gst_query_writable_structure(self.as_mut_ptr());
66            StructureRef::from_glib_borrow_mut(structure)
67        }
68    }
69
70    #[doc(alias = "GST_QUERY_IS_DOWNSTREAM")]
71    #[inline]
72    pub fn is_downstream(&self) -> bool {
73        unsafe { ((*self.as_ptr()).type_ as u32) & ffi::GST_QUERY_TYPE_DOWNSTREAM != 0 }
74    }
75
76    #[doc(alias = "GST_QUERY_IS_UPSTREAM")]
77    #[inline]
78    pub fn is_upstream(&self) -> bool {
79        unsafe { ((*self.as_ptr()).type_ as u32) & ffi::GST_QUERY_TYPE_UPSTREAM != 0 }
80    }
81
82    #[doc(alias = "GST_QUERY_IS_SERIALIZED")]
83    #[inline]
84    pub fn is_serialized(&self) -> bool {
85        unsafe { ((*self.as_ptr()).type_ as u32) & ffi::GST_QUERY_TYPE_SERIALIZED != 0 }
86    }
87
88    #[doc(alias = "get_type")]
89    #[doc(alias = "GST_QUERY_TYPE")]
90    #[inline]
91    pub fn type_(&self) -> QueryType {
92        unsafe { from_glib((*self.as_ptr()).type_) }
93    }
94
95    pub fn view(&self) -> QueryView {
96        unsafe {
97            let type_ = (*self.as_ptr()).type_;
98
99            match type_ {
100                ffi::GST_QUERY_POSITION => Position::view(self),
101                ffi::GST_QUERY_DURATION => Duration::view(self),
102                ffi::GST_QUERY_LATENCY => Latency::view(self),
103                ffi::GST_QUERY_SEEKING => Seeking::view(self),
104                ffi::GST_QUERY_SEGMENT => Segment::view(self),
105                ffi::GST_QUERY_CONVERT => Convert::view(self),
106                ffi::GST_QUERY_FORMATS => Formats::view(self),
107                ffi::GST_QUERY_BUFFERING => Buffering::view(self),
108                ffi::GST_QUERY_CUSTOM => Custom::view(self),
109                ffi::GST_QUERY_URI => Uri::view(self),
110                ffi::GST_QUERY_ALLOCATION => Allocation::view(self),
111                ffi::GST_QUERY_SCHEDULING => Scheduling::view(self),
112                ffi::GST_QUERY_ACCEPT_CAPS => AcceptCaps::view(self),
113                ffi::GST_QUERY_CAPS => Caps::view(self),
114                ffi::GST_QUERY_DRAIN => Drain::view(self),
115                ffi::GST_QUERY_CONTEXT => Context::view(self),
116                #[cfg(feature = "v1_16")]
117                ffi::GST_QUERY_BITRATE => Bitrate::view(self),
118                #[cfg(feature = "v1_22")]
119                ffi::GST_QUERY_SELECTABLE => Selectable::view(self),
120                _ => Other::view(self),
121            }
122        }
123    }
124
125    pub fn view_mut(&mut self) -> QueryViewMut {
126        unsafe {
127            let type_ = (*self.as_ptr()).type_;
128
129            match type_ {
130                ffi::GST_QUERY_POSITION => Position::view_mut(self),
131                ffi::GST_QUERY_DURATION => Duration::view_mut(self),
132                ffi::GST_QUERY_LATENCY => Latency::view_mut(self),
133                ffi::GST_QUERY_SEEKING => Seeking::view_mut(self),
134                ffi::GST_QUERY_SEGMENT => Segment::view_mut(self),
135                ffi::GST_QUERY_CONVERT => Convert::view_mut(self),
136                ffi::GST_QUERY_FORMATS => Formats::view_mut(self),
137                ffi::GST_QUERY_BUFFERING => Buffering::view_mut(self),
138                ffi::GST_QUERY_CUSTOM => Custom::view_mut(self),
139                ffi::GST_QUERY_URI => Uri::view_mut(self),
140                ffi::GST_QUERY_ALLOCATION => Allocation::view_mut(self),
141                ffi::GST_QUERY_SCHEDULING => Scheduling::view_mut(self),
142                ffi::GST_QUERY_ACCEPT_CAPS => AcceptCaps::view_mut(self),
143                ffi::GST_QUERY_CAPS => Caps::view_mut(self),
144                ffi::GST_QUERY_DRAIN => Drain::view_mut(self),
145                ffi::GST_QUERY_CONTEXT => Context::view_mut(self),
146                #[cfg(feature = "v1_16")]
147                ffi::GST_QUERY_BITRATE => Bitrate::view_mut(self),
148                #[cfg(feature = "v1_22")]
149                ffi::GST_QUERY_SELECTABLE => Selectable::view_mut(self),
150                _ => Other::view_mut(self),
151            }
152        }
153    }
154}
155
156impl fmt::Debug for Query {
157    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
158        QueryRef::fmt(self, f)
159    }
160}
161
162impl fmt::Debug for QueryRef {
163    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164        f.debug_struct("Query")
165            .field("ptr", &self.as_ptr())
166            .field("type", &unsafe {
167                let type_ = ffi::gst_query_type_get_name((*self.as_ptr()).type_);
168                CStr::from_ptr(type_).to_str().unwrap()
169            })
170            .field("structure", &self.structure())
171            .finish()
172    }
173}
174
175#[derive(Debug)]
176#[non_exhaustive]
177pub enum QueryView<'a> {
178    Position(&'a Position),
179    Duration(&'a Duration),
180    Latency(&'a Latency),
181    Seeking(&'a Seeking),
182    Segment(&'a Segment),
183    Convert(&'a Convert),
184    Formats(&'a Formats),
185    Buffering(&'a Buffering),
186    Custom(&'a Custom),
187    Uri(&'a Uri),
188    Allocation(&'a Allocation),
189    Scheduling(&'a Scheduling),
190    AcceptCaps(&'a AcceptCaps),
191    Caps(&'a Caps),
192    Drain(&'a Drain),
193    Context(&'a Context),
194    #[cfg(feature = "v1_16")]
195    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
196    Bitrate(&'a Bitrate),
197    #[cfg(feature = "v1_22")]
198    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
199    Selectable(&'a Selectable),
200    Other(&'a Other),
201}
202
203#[derive(Debug)]
204#[non_exhaustive]
205pub enum QueryViewMut<'a> {
206    Position(&'a mut Position),
207    Duration(&'a mut Duration),
208    Latency(&'a mut Latency),
209    Seeking(&'a mut Seeking),
210    Segment(&'a mut Segment),
211    Convert(&'a mut Convert),
212    Formats(&'a mut Formats),
213    Buffering(&'a mut Buffering),
214    Custom(&'a mut Custom),
215    Uri(&'a mut Uri),
216    Allocation(&'a mut Allocation),
217    Scheduling(&'a mut Scheduling),
218    AcceptCaps(&'a mut AcceptCaps),
219    Caps(&'a mut Caps),
220    Drain(&'a mut Drain),
221    Context(&'a mut Context),
222    #[cfg(feature = "v1_16")]
223    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
224    Bitrate(&'a mut Bitrate),
225    #[cfg(feature = "v1_22")]
226    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
227    Selectable(&'a mut Selectable),
228    Other(&'a mut Other),
229}
230
231macro_rules! declare_concrete_query(
232    ($name:ident, $param:ident) => {
233        #[repr(transparent)]
234        pub struct $name<$param = QueryRef>($param);
235
236        impl $name {
237            #[inline]
238            pub fn query(&self) -> &QueryRef {
239                unsafe { &*(self as *const Self as *const QueryRef) }
240            }
241
242            #[inline]
243            pub fn query_mut(&mut self) -> &mut QueryRef {
244                unsafe { &mut *(self as *mut Self as *mut QueryRef) }
245            }
246
247            #[inline]
248            unsafe fn view(query: &QueryRef) -> QueryView<'_> {
249                let query = &*(query as *const QueryRef as *const Self);
250                QueryView::$name(query)
251            }
252
253            #[inline]
254            unsafe fn view_mut(query: &mut QueryRef) -> QueryViewMut<'_> {
255                let query = &mut *(query as *mut QueryRef as *mut Self);
256                QueryViewMut::$name(query)
257            }
258        }
259
260        impl Deref for $name {
261            type Target = QueryRef;
262
263            #[inline]
264            fn deref(&self) -> &Self::Target {
265                self.query()
266            }
267        }
268
269        impl DerefMut for $name {
270            #[inline]
271            fn deref_mut(&mut self) -> &mut Self::Target {
272                self.query_mut()
273            }
274        }
275
276        impl ToOwned for $name {
277            type Owned = $name<Query>;
278
279            #[inline]
280            fn to_owned(&self) -> Self::Owned {
281                $name::<Query>(self.copy())
282            }
283        }
284
285        impl $name<Query> {
286            #[inline]
287            pub fn get_mut(&mut self) -> Option<&mut $name> {
288                self.0
289                    .get_mut()
290                    .map(|query| unsafe { &mut *(query as *mut QueryRef as *mut $name) })
291            }
292        }
293
294        impl Deref for $name<Query> {
295            type Target = $name;
296
297            #[inline]
298            fn deref(&self) -> &Self::Target {
299                unsafe { &*(self.0.as_ptr() as *const Self::Target) }
300            }
301        }
302
303        impl DerefMut for $name<Query> {
304            #[inline]
305            fn deref_mut(&mut self) -> &mut Self::Target {
306                debug_assert!(self.0.is_writable());
307                unsafe { &mut *(self.0.as_mut_ptr() as *mut Self::Target) }
308            }
309        }
310
311        impl Borrow<$name> for $name<Query> {
312            #[inline]
313            fn borrow(&self) -> &$name {
314                &*self
315            }
316        }
317
318        impl BorrowMut<$name> for $name<Query> {
319            #[inline]
320            fn borrow_mut(&mut self) -> &mut $name {
321                &mut *self
322            }
323        }
324
325        impl From<$name<Query>> for Query {
326            #[inline]
327            fn from(concrete: $name<Query>) -> Self {
328                skip_assert_initialized!();
329                concrete.0
330            }
331        }
332    }
333);
334
335declare_concrete_query!(Position, T);
336impl Position<Query> {
337    #[doc(alias = "gst_query_new_position")]
338    pub fn new(fmt: crate::Format) -> Self {
339        assert_initialized_main_thread!();
340        unsafe { Self(from_glib_full(ffi::gst_query_new_position(fmt.into_glib()))) }
341    }
342}
343
344impl Position {
345    #[doc(alias = "get_result")]
346    #[doc(alias = "gst_query_parse_position")]
347    pub fn result(&self) -> GenericFormattedValue {
348        unsafe {
349            let mut fmt = mem::MaybeUninit::uninit();
350            let mut pos = mem::MaybeUninit::uninit();
351
352            ffi::gst_query_parse_position(self.as_mut_ptr(), fmt.as_mut_ptr(), pos.as_mut_ptr());
353
354            GenericFormattedValue::new(from_glib(fmt.assume_init()), pos.assume_init())
355        }
356    }
357
358    #[doc(alias = "get_format")]
359    #[doc(alias = "gst_query_parse_position")]
360    pub fn format(&self) -> crate::Format {
361        unsafe {
362            let mut fmt = mem::MaybeUninit::uninit();
363
364            ffi::gst_query_parse_position(self.as_mut_ptr(), fmt.as_mut_ptr(), ptr::null_mut());
365
366            from_glib(fmt.assume_init())
367        }
368    }
369
370    #[doc(alias = "gst_query_set_position")]
371    pub fn set(&mut self, pos: impl FormattedValue) {
372        assert_eq!(pos.format(), self.format());
373        unsafe {
374            ffi::gst_query_set_position(
375                self.as_mut_ptr(),
376                pos.format().into_glib(),
377                pos.into_raw_value(),
378            );
379        }
380    }
381}
382
383impl std::fmt::Debug for Position {
384    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
385        f.debug_struct("Position")
386            .field("structure", &self.query().structure())
387            .field("result", &self.result())
388            .field("format", &self.format())
389            .finish()
390    }
391}
392
393impl std::fmt::Debug for Position<Query> {
394    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395        Position::<QueryRef>::fmt(self, f)
396    }
397}
398
399declare_concrete_query!(Duration, T);
400impl Duration<Query> {
401    #[doc(alias = "gst_query_new_duration")]
402    pub fn new(fmt: crate::Format) -> Self {
403        assert_initialized_main_thread!();
404        unsafe { Self(from_glib_full(ffi::gst_query_new_duration(fmt.into_glib()))) }
405    }
406}
407
408impl Duration {
409    #[doc(alias = "get_result")]
410    #[doc(alias = "gst_query_parse_duration")]
411    pub fn result(&self) -> GenericFormattedValue {
412        unsafe {
413            let mut fmt = mem::MaybeUninit::uninit();
414            let mut pos = mem::MaybeUninit::uninit();
415
416            ffi::gst_query_parse_duration(self.as_mut_ptr(), fmt.as_mut_ptr(), pos.as_mut_ptr());
417
418            GenericFormattedValue::new(from_glib(fmt.assume_init()), pos.assume_init())
419        }
420    }
421
422    #[doc(alias = "get_format")]
423    #[doc(alias = "gst_query_parse_duration")]
424    pub fn format(&self) -> crate::Format {
425        unsafe {
426            let mut fmt = mem::MaybeUninit::uninit();
427
428            ffi::gst_query_parse_duration(self.as_mut_ptr(), fmt.as_mut_ptr(), ptr::null_mut());
429
430            from_glib(fmt.assume_init())
431        }
432    }
433
434    #[doc(alias = "gst_query_set_duration")]
435    pub fn set(&mut self, dur: impl FormattedValue) {
436        assert_eq!(dur.format(), self.format());
437        unsafe {
438            ffi::gst_query_set_duration(
439                self.as_mut_ptr(),
440                dur.format().into_glib(),
441                dur.into_raw_value(),
442            );
443        }
444    }
445}
446
447impl std::fmt::Debug for Duration {
448    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
449        f.debug_struct("Duration")
450            .field("structure", &self.query().structure())
451            .field("result", &self.result())
452            .field("format", &self.format())
453            .finish()
454    }
455}
456
457impl std::fmt::Debug for Duration<Query> {
458    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
459        Duration::<QueryRef>::fmt(self, f)
460    }
461}
462
463declare_concrete_query!(Latency, T);
464impl Latency<Query> {
465    #[doc(alias = "gst_query_new_latency")]
466    pub fn new() -> Self {
467        assert_initialized_main_thread!();
468        unsafe { Self(from_glib_full(ffi::gst_query_new_latency())) }
469    }
470}
471
472impl Default for Latency<Query> {
473    fn default() -> Self {
474        Self::new()
475    }
476}
477
478impl Latency {
479    #[doc(alias = "get_result")]
480    #[doc(alias = "gst_query_parse_latency")]
481    pub fn result(&self) -> (bool, crate::ClockTime, Option<crate::ClockTime>) {
482        unsafe {
483            let mut live = mem::MaybeUninit::uninit();
484            let mut min = mem::MaybeUninit::uninit();
485            let mut max = mem::MaybeUninit::uninit();
486
487            ffi::gst_query_parse_latency(
488                self.as_mut_ptr(),
489                live.as_mut_ptr(),
490                min.as_mut_ptr(),
491                max.as_mut_ptr(),
492            );
493
494            (
495                from_glib(live.assume_init()),
496                try_from_glib(min.assume_init()).expect("undefined min latency"),
497                from_glib(max.assume_init()),
498            )
499        }
500    }
501
502    #[doc(alias = "gst_query_set_latency")]
503    pub fn set(
504        &mut self,
505        live: bool,
506        min: crate::ClockTime,
507        max: impl Into<Option<crate::ClockTime>>,
508    ) {
509        unsafe {
510            ffi::gst_query_set_latency(
511                self.as_mut_ptr(),
512                live.into_glib(),
513                min.into_glib(),
514                max.into().into_glib(),
515            );
516        }
517    }
518}
519
520impl std::fmt::Debug for Latency {
521    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
522        f.debug_struct("Latency")
523            .field("structure", &self.query().structure())
524            .field("result", &self.result())
525            .finish()
526    }
527}
528
529impl std::fmt::Debug for Latency<Query> {
530    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
531        Latency::<QueryRef>::fmt(self, f)
532    }
533}
534
535declare_concrete_query!(Seeking, T);
536impl Seeking<Query> {
537    #[doc(alias = "gst_query_new_seeking")]
538    pub fn new(fmt: crate::Format) -> Self {
539        assert_initialized_main_thread!();
540        unsafe { Self(from_glib_full(ffi::gst_query_new_seeking(fmt.into_glib()))) }
541    }
542}
543
544impl Seeking {
545    #[doc(alias = "get_result")]
546    #[doc(alias = "gst_query_parse_seeking")]
547    pub fn result(&self) -> (bool, GenericFormattedValue, GenericFormattedValue) {
548        unsafe {
549            let mut fmt = mem::MaybeUninit::uninit();
550            let mut seekable = mem::MaybeUninit::uninit();
551            let mut start = mem::MaybeUninit::uninit();
552            let mut end = mem::MaybeUninit::uninit();
553            ffi::gst_query_parse_seeking(
554                self.as_mut_ptr(),
555                fmt.as_mut_ptr(),
556                seekable.as_mut_ptr(),
557                start.as_mut_ptr(),
558                end.as_mut_ptr(),
559            );
560
561            (
562                from_glib(seekable.assume_init()),
563                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
564                GenericFormattedValue::new(from_glib(fmt.assume_init()), end.assume_init()),
565            )
566        }
567    }
568
569    #[doc(alias = "get_format")]
570    #[doc(alias = "gst_query_parse_seeking")]
571    pub fn format(&self) -> crate::Format {
572        unsafe {
573            let mut fmt = mem::MaybeUninit::uninit();
574            ffi::gst_query_parse_seeking(
575                self.as_mut_ptr(),
576                fmt.as_mut_ptr(),
577                ptr::null_mut(),
578                ptr::null_mut(),
579                ptr::null_mut(),
580            );
581
582            from_glib(fmt.assume_init())
583        }
584    }
585
586    #[doc(alias = "gst_query_set_seeking")]
587    pub fn set<V: FormattedValue>(
588        &mut self,
589        seekable: bool,
590        start: V,
591        end: impl CompatibleFormattedValue<V>,
592    ) {
593        assert_eq!(self.format(), start.format());
594        let end = end.try_into_checked(start).unwrap();
595
596        unsafe {
597            ffi::gst_query_set_seeking(
598                self.as_mut_ptr(),
599                start.format().into_glib(),
600                seekable.into_glib(),
601                start.into_raw_value(),
602                end.into_raw_value(),
603            );
604        }
605    }
606}
607
608impl std::fmt::Debug for Seeking {
609    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
610        f.debug_struct("Seeking")
611            .field("structure", &self.query().structure())
612            .field("result", &self.result())
613            .field("format", &self.format())
614            .finish()
615    }
616}
617
618impl std::fmt::Debug for Seeking<Query> {
619    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
620        Seeking::<QueryRef>::fmt(self, f)
621    }
622}
623
624declare_concrete_query!(Segment, T);
625impl Segment<Query> {
626    #[doc(alias = "gst_query_new_segment")]
627    pub fn new(fmt: crate::Format) -> Self {
628        assert_initialized_main_thread!();
629        unsafe { Self(from_glib_full(ffi::gst_query_new_segment(fmt.into_glib()))) }
630    }
631}
632
633impl Segment {
634    #[doc(alias = "get_result")]
635    #[doc(alias = "gst_query_parse_segment")]
636    pub fn result(&self) -> (f64, GenericFormattedValue, GenericFormattedValue) {
637        unsafe {
638            let mut rate = mem::MaybeUninit::uninit();
639            let mut fmt = mem::MaybeUninit::uninit();
640            let mut start = mem::MaybeUninit::uninit();
641            let mut stop = mem::MaybeUninit::uninit();
642
643            ffi::gst_query_parse_segment(
644                self.as_mut_ptr(),
645                rate.as_mut_ptr(),
646                fmt.as_mut_ptr(),
647                start.as_mut_ptr(),
648                stop.as_mut_ptr(),
649            );
650            (
651                rate.assume_init(),
652                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
653                GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
654            )
655        }
656    }
657
658    #[doc(alias = "get_format")]
659    #[doc(alias = "gst_query_parse_segment")]
660    pub fn format(&self) -> crate::Format {
661        unsafe {
662            let mut fmt = mem::MaybeUninit::uninit();
663
664            ffi::gst_query_parse_segment(
665                self.as_mut_ptr(),
666                ptr::null_mut(),
667                fmt.as_mut_ptr(),
668                ptr::null_mut(),
669                ptr::null_mut(),
670            );
671            from_glib(fmt.assume_init())
672        }
673    }
674
675    #[doc(alias = "gst_query_set_segment")]
676    pub fn set<V: FormattedValue>(
677        &mut self,
678        rate: f64,
679        start: V,
680        stop: impl CompatibleFormattedValue<V>,
681    ) {
682        let stop = stop.try_into_checked(start).unwrap();
683
684        unsafe {
685            ffi::gst_query_set_segment(
686                self.as_mut_ptr(),
687                rate,
688                start.format().into_glib(),
689                start.into_raw_value(),
690                stop.into_raw_value(),
691            );
692        }
693    }
694}
695
696impl std::fmt::Debug for Segment {
697    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
698        f.debug_struct("Segment")
699            .field("structure", &self.query().structure())
700            .field("result", &self.result())
701            .field("format", &self.format())
702            .finish()
703    }
704}
705
706impl std::fmt::Debug for Segment<Query> {
707    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
708        Segment::<QueryRef>::fmt(self, f)
709    }
710}
711
712declare_concrete_query!(Convert, T);
713impl Convert<Query> {
714    #[doc(alias = "gst_query_new_convert")]
715    pub fn new(value: impl FormattedValue, dest_fmt: crate::Format) -> Self {
716        assert_initialized_main_thread!();
717        unsafe {
718            Self(from_glib_full(ffi::gst_query_new_convert(
719                value.format().into_glib(),
720                value.into_raw_value(),
721                dest_fmt.into_glib(),
722            )))
723        }
724    }
725}
726
727impl Convert {
728    #[doc(alias = "get_result")]
729    #[doc(alias = "gst_query_parse_convert")]
730    pub fn result(&self) -> (GenericFormattedValue, GenericFormattedValue) {
731        unsafe {
732            let mut src_fmt = mem::MaybeUninit::uninit();
733            let mut src = mem::MaybeUninit::uninit();
734            let mut dest_fmt = mem::MaybeUninit::uninit();
735            let mut dest = mem::MaybeUninit::uninit();
736
737            ffi::gst_query_parse_convert(
738                self.as_mut_ptr(),
739                src_fmt.as_mut_ptr(),
740                src.as_mut_ptr(),
741                dest_fmt.as_mut_ptr(),
742                dest.as_mut_ptr(),
743            );
744            (
745                GenericFormattedValue::new(from_glib(src_fmt.assume_init()), src.assume_init()),
746                GenericFormattedValue::new(from_glib(dest_fmt.assume_init()), dest.assume_init()),
747            )
748        }
749    }
750
751    #[doc(alias = "gst_query_parse_convert")]
752    pub fn get(&self) -> (GenericFormattedValue, crate::Format) {
753        unsafe {
754            let mut src_fmt = mem::MaybeUninit::uninit();
755            let mut src = mem::MaybeUninit::uninit();
756            let mut dest_fmt = mem::MaybeUninit::uninit();
757
758            ffi::gst_query_parse_convert(
759                self.as_mut_ptr(),
760                src_fmt.as_mut_ptr(),
761                src.as_mut_ptr(),
762                dest_fmt.as_mut_ptr(),
763                ptr::null_mut(),
764            );
765            (
766                GenericFormattedValue::new(from_glib(src_fmt.assume_init()), src.assume_init()),
767                from_glib(dest_fmt.assume_init()),
768            )
769        }
770    }
771
772    #[doc(alias = "gst_query_set_convert")]
773    pub fn set(&mut self, src: impl FormattedValue, dest: impl FormattedValue) {
774        unsafe {
775            ffi::gst_query_set_convert(
776                self.as_mut_ptr(),
777                src.format().into_glib(),
778                src.into_raw_value(),
779                dest.format().into_glib(),
780                dest.into_raw_value(),
781            );
782        }
783    }
784}
785
786impl std::fmt::Debug for Convert {
787    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
788        let (source, dest) = self.result();
789
790        f.debug_struct("Convert")
791            .field("structure", &self.query().structure())
792            .field("source", &source)
793            .field("dest", &dest)
794            .finish()
795    }
796}
797
798impl std::fmt::Debug for Convert<Query> {
799    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
800        Convert::<QueryRef>::fmt(self, f)
801    }
802}
803
804declare_concrete_query!(Formats, T);
805impl Formats<Query> {
806    #[doc(alias = "gst_query_new_formats")]
807    pub fn new() -> Self {
808        assert_initialized_main_thread!();
809        unsafe { Self(from_glib_full(ffi::gst_query_new_formats())) }
810    }
811}
812
813impl Default for Formats<Query> {
814    fn default() -> Self {
815        Self::new()
816    }
817}
818
819impl Formats {
820    #[doc(alias = "get_result")]
821    #[doc(alias = "gst_query_parse_n_formats")]
822    #[doc(alias = "gst_query_parse_nth_format")]
823    pub fn result(&self) -> FormatsIter<'_> {
824        FormatsIter::new(self)
825    }
826
827    #[doc(alias = "gst_query_set_formats")]
828    #[doc(alias = "gst_query_set_formatsv")]
829    pub fn set(&mut self, formats: impl IntoIterator<Item = crate::Format>) {
830        unsafe {
831            let v = formats
832                .into_iter()
833                .map(|f| f.into_glib())
834                .collect::<SmallVec<[_; 8]>>();
835            ffi::gst_query_set_formatsv(self.as_mut_ptr(), v.len() as i32, v.as_ptr() as *mut _);
836        }
837    }
838}
839
840impl std::fmt::Debug for Formats {
841    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
842        struct FormatsDebug<'a>(&'a Formats);
843
844        impl std::fmt::Debug for FormatsDebug<'_> {
845            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
846                f.debug_list().entries(self.0.result()).finish()
847            }
848        }
849
850        f.debug_struct("Formats")
851            .field("structure", &self.query().structure())
852            .field("result", &FormatsDebug(self))
853            .finish()
854    }
855}
856
857impl std::fmt::Debug for Formats<Query> {
858    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
859        Formats::<QueryRef>::fmt(self, f)
860    }
861}
862
863crate::utils::define_fixed_size_iter!(
864    FormatsIter,
865    &'a Formats,
866    crate::Format,
867    |collection: &Formats| unsafe {
868        let mut n = mem::MaybeUninit::uninit();
869        ffi::gst_query_parse_n_formats(collection.as_mut_ptr(), n.as_mut_ptr());
870        n.assume_init() as usize
871    },
872    |collection: &Formats, idx: usize| unsafe {
873        let mut fmt = mem::MaybeUninit::uninit();
874        ffi::gst_query_parse_nth_format(collection.as_mut_ptr(), idx as u32, fmt.as_mut_ptr());
875        from_glib(fmt.assume_init())
876    }
877);
878
879declare_concrete_query!(Buffering, T);
880impl Buffering<Query> {
881    #[doc(alias = "gst_query_new_buffering")]
882    pub fn new(fmt: crate::Format) -> Self {
883        assert_initialized_main_thread!();
884        unsafe {
885            Self(from_glib_full(ffi::gst_query_new_buffering(
886                fmt.into_glib(),
887            )))
888        }
889    }
890}
891
892impl Buffering {
893    #[doc(alias = "get_format")]
894    #[doc(alias = "gst_query_parse_buffering_range")]
895    pub fn format(&self) -> crate::Format {
896        unsafe {
897            let mut fmt = mem::MaybeUninit::uninit();
898
899            ffi::gst_query_parse_buffering_range(
900                self.as_mut_ptr(),
901                fmt.as_mut_ptr(),
902                ptr::null_mut(),
903                ptr::null_mut(),
904                ptr::null_mut(),
905            );
906
907            from_glib(fmt.assume_init())
908        }
909    }
910
911    #[doc(alias = "get_percent")]
912    #[doc(alias = "gst_query_parse_buffering_percent")]
913    pub fn percent(&self) -> (bool, i32) {
914        unsafe {
915            let mut busy = mem::MaybeUninit::uninit();
916            let mut percent = mem::MaybeUninit::uninit();
917
918            ffi::gst_query_parse_buffering_percent(
919                self.as_mut_ptr(),
920                busy.as_mut_ptr(),
921                percent.as_mut_ptr(),
922            );
923
924            (from_glib(busy.assume_init()), percent.assume_init())
925        }
926    }
927
928    #[doc(alias = "get_range")]
929    #[doc(alias = "gst_query_parse_buffering_range")]
930    pub fn range(&self) -> (GenericFormattedValue, GenericFormattedValue, i64) {
931        unsafe {
932            let mut fmt = mem::MaybeUninit::uninit();
933            let mut start = mem::MaybeUninit::uninit();
934            let mut stop = mem::MaybeUninit::uninit();
935            let mut estimated_total = mem::MaybeUninit::uninit();
936
937            ffi::gst_query_parse_buffering_range(
938                self.as_mut_ptr(),
939                fmt.as_mut_ptr(),
940                start.as_mut_ptr(),
941                stop.as_mut_ptr(),
942                estimated_total.as_mut_ptr(),
943            );
944            (
945                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
946                GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
947                estimated_total.assume_init(),
948            )
949        }
950    }
951
952    #[doc(alias = "get_stats")]
953    #[doc(alias = "gst_query_parse_buffering_stats")]
954    pub fn stats(&self) -> (crate::BufferingMode, i32, i32, i64) {
955        unsafe {
956            let mut mode = mem::MaybeUninit::uninit();
957            let mut avg_in = mem::MaybeUninit::uninit();
958            let mut avg_out = mem::MaybeUninit::uninit();
959            let mut buffering_left = mem::MaybeUninit::uninit();
960
961            ffi::gst_query_parse_buffering_stats(
962                self.as_mut_ptr(),
963                mode.as_mut_ptr(),
964                avg_in.as_mut_ptr(),
965                avg_out.as_mut_ptr(),
966                buffering_left.as_mut_ptr(),
967            );
968
969            (
970                from_glib(mode.assume_init()),
971                avg_in.assume_init(),
972                avg_out.assume_init(),
973                buffering_left.assume_init(),
974            )
975        }
976    }
977
978    #[doc(alias = "get_ranges")]
979    #[doc(alias = "gst_query_get_n_buffering_ranges")]
980    #[doc(alias = "gst_query_parse_nth_buffering_range")]
981    pub fn ranges(&self) -> RangesIter<'_> {
982        RangesIter::new(self)
983    }
984
985    #[doc(alias = "gst_query_set_buffering_percent")]
986    pub fn set_percent(&mut self, busy: bool, percent: i32) {
987        unsafe {
988            ffi::gst_query_set_buffering_percent(self.as_mut_ptr(), busy.into_glib(), percent);
989        }
990    }
991
992    #[doc(alias = "gst_query_set_buffering_range")]
993    pub fn set_range<V: FormattedValue>(
994        &mut self,
995        start: V,
996        stop: impl CompatibleFormattedValue<V>,
997        estimated_total: i64,
998    ) {
999        assert_eq!(self.format(), start.format());
1000        let stop = stop.try_into_checked(start).unwrap();
1001
1002        unsafe {
1003            ffi::gst_query_set_buffering_range(
1004                self.as_mut_ptr(),
1005                start.format().into_glib(),
1006                start.into_raw_value(),
1007                stop.into_raw_value(),
1008                estimated_total,
1009            );
1010        }
1011    }
1012
1013    #[doc(alias = "gst_query_set_buffering_stats")]
1014    pub fn set_stats(
1015        &mut self,
1016        mode: crate::BufferingMode,
1017        avg_in: i32,
1018        avg_out: i32,
1019        buffering_left: i64,
1020    ) {
1021        skip_assert_initialized!();
1022        unsafe {
1023            ffi::gst_query_set_buffering_stats(
1024                self.as_mut_ptr(),
1025                mode.into_glib(),
1026                avg_in,
1027                avg_out,
1028                buffering_left,
1029            );
1030        }
1031    }
1032
1033    #[doc(alias = "gst_query_add_buffering_range")]
1034    pub fn add_buffering_ranges<V: FormattedValue, U: CompatibleFormattedValue<V> + Copy>(
1035        &mut self,
1036        ranges: impl IntoIterator<Item = (V, U)>,
1037    ) {
1038        unsafe {
1039            let fmt = self.format();
1040
1041            for (start, stop) in ranges.into_iter() {
1042                assert_eq!(start.format(), fmt);
1043                let stop = stop.try_into_checked(start).unwrap();
1044                ffi::gst_query_add_buffering_range(
1045                    self.as_mut_ptr(),
1046                    start.into_raw_value(),
1047                    stop.into_raw_value(),
1048                );
1049            }
1050        }
1051    }
1052}
1053
1054impl std::fmt::Debug for Buffering {
1055    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1056        struct RangesDebug<'a>(&'a Buffering);
1057
1058        impl std::fmt::Debug for RangesDebug<'_> {
1059            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1060                f.debug_list().entries(self.0.ranges()).finish()
1061            }
1062        }
1063
1064        f.debug_struct("Buffering")
1065            .field("structure", &self.query().structure())
1066            .field("format", &self.format())
1067            .field("percent", &self.percent())
1068            .field("range", &RangesDebug(self))
1069            .finish()
1070    }
1071}
1072
1073impl std::fmt::Debug for Buffering<Query> {
1074    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1075        Buffering::<QueryRef>::fmt(self, f)
1076    }
1077}
1078
1079crate::utils::define_fixed_size_iter!(
1080    RangesIter,
1081    &'a Buffering,
1082    (GenericFormattedValue, GenericFormattedValue),
1083    |collection: &Buffering| unsafe {
1084        ffi::gst_query_get_n_buffering_ranges(collection.as_mut_ptr()) as usize
1085    },
1086    |collection: &Buffering, idx: usize| unsafe {
1087        let mut fmt = mem::MaybeUninit::uninit();
1088        ffi::gst_query_parse_buffering_range(
1089            collection.as_mut_ptr(),
1090            fmt.as_mut_ptr(),
1091            ptr::null_mut(),
1092            ptr::null_mut(),
1093            ptr::null_mut(),
1094        );
1095        let fmt = from_glib(fmt.assume_init());
1096
1097        let mut start = mem::MaybeUninit::uninit();
1098        let mut stop = mem::MaybeUninit::uninit();
1099        ffi::gst_query_parse_nth_buffering_range(
1100            collection.as_mut_ptr(),
1101            idx as u32,
1102            start.as_mut_ptr(),
1103            stop.as_mut_ptr(),
1104        );
1105
1106        (
1107            GenericFormattedValue::new(fmt, start.assume_init()),
1108            GenericFormattedValue::new(fmt, stop.assume_init()),
1109        )
1110    }
1111);
1112
1113declare_concrete_query!(Custom, T);
1114impl Custom<Query> {
1115    #[doc(alias = "gst_query_new_custom")]
1116    pub fn new(structure: crate::Structure) -> Self {
1117        skip_assert_initialized!();
1118        unsafe {
1119            Self(from_glib_full(ffi::gst_query_new_custom(
1120                ffi::GST_QUERY_CUSTOM,
1121                structure.into_glib_ptr(),
1122            )))
1123        }
1124    }
1125}
1126
1127impl std::fmt::Debug for Custom {
1128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1129        f.debug_struct("Custom")
1130            .field("structure", &self.query().structure())
1131            .finish()
1132    }
1133}
1134
1135impl std::fmt::Debug for Custom<Query> {
1136    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1137        Custom::<QueryRef>::fmt(self, f)
1138    }
1139}
1140
1141declare_concrete_query!(Uri, T);
1142impl Uri<Query> {
1143    #[doc(alias = "gst_query_new_uri")]
1144    pub fn new() -> Self {
1145        assert_initialized_main_thread!();
1146        unsafe { Self(from_glib_full(ffi::gst_query_new_uri())) }
1147    }
1148}
1149
1150impl Default for Uri<Query> {
1151    fn default() -> Self {
1152        Self::new()
1153    }
1154}
1155
1156impl Uri {
1157    #[doc(alias = "get_uri")]
1158    #[doc(alias = "gst_query_parse_uri")]
1159    pub fn uri(&self) -> Option<glib::GString> {
1160        unsafe {
1161            let mut uri = ptr::null_mut();
1162            ffi::gst_query_parse_uri(self.as_mut_ptr(), &mut uri);
1163            from_glib_full(uri)
1164        }
1165    }
1166
1167    #[doc(alias = "get_redirection")]
1168    #[doc(alias = "gst_query_parse_uri_redirection")]
1169    #[doc(alias = "gst_query_parse_uri_redirection_permanent")]
1170    pub fn redirection(&self) -> (Option<glib::GString>, bool) {
1171        unsafe {
1172            let mut uri = ptr::null_mut();
1173            ffi::gst_query_parse_uri_redirection(self.as_mut_ptr(), &mut uri);
1174            let mut permanent = mem::MaybeUninit::uninit();
1175            ffi::gst_query_parse_uri_redirection_permanent(
1176                self.as_mut_ptr(),
1177                permanent.as_mut_ptr(),
1178            );
1179
1180            (from_glib_full(uri), from_glib(permanent.assume_init()))
1181        }
1182    }
1183
1184    #[doc(alias = "gst_query_set_uri")]
1185    pub fn set_uri<'a, T>(&mut self, uri: impl Into<Option<&'a T>>)
1186    where
1187        T: 'a + AsRef<str> + ?Sized,
1188    {
1189        unsafe {
1190            ffi::gst_query_set_uri(
1191                self.as_mut_ptr(),
1192                uri.into().map(AsRef::as_ref).to_glib_none().0,
1193            );
1194        }
1195    }
1196
1197    #[doc(alias = "gst_query_set_uri_redirection")]
1198    #[doc(alias = "gst_query_set_uri_redirection_permanent")]
1199    pub fn set_redirection<'a, T>(&mut self, uri: impl Into<Option<&'a T>>, permanent: bool)
1200    where
1201        T: 'a + AsRef<str> + ?Sized,
1202    {
1203        unsafe {
1204            ffi::gst_query_set_uri_redirection(
1205                self.as_mut_ptr(),
1206                uri.into().map(AsRef::as_ref).to_glib_none().0,
1207            );
1208            ffi::gst_query_set_uri_redirection_permanent(
1209                self.0.as_mut_ptr(),
1210                permanent.into_glib(),
1211            );
1212        }
1213    }
1214}
1215
1216impl std::fmt::Debug for Uri {
1217    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1218        let (redirection, permanent) = self.redirection();
1219        f.debug_struct("Uri")
1220            .field("structure", &self.query().structure())
1221            .field("uri", &self.uri())
1222            .field("redirection", &redirection)
1223            .field("redirection-permanent", &permanent)
1224            .finish()
1225    }
1226}
1227
1228impl std::fmt::Debug for Uri<Query> {
1229    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1230        Uri::<QueryRef>::fmt(self, f)
1231    }
1232}
1233
1234declare_concrete_query!(Allocation, T);
1235impl Allocation<Query> {
1236    #[doc(alias = "gst_query_new_allocation")]
1237    pub fn new(caps: Option<&crate::Caps>, need_pool: bool) -> Self {
1238        skip_assert_initialized!();
1239        unsafe {
1240            Self(from_glib_full(ffi::gst_query_new_allocation(
1241                caps.map(|caps| caps.as_mut_ptr())
1242                    .unwrap_or(ptr::null_mut()),
1243                need_pool.into_glib(),
1244            )))
1245        }
1246    }
1247}
1248
1249impl Allocation {
1250    #[doc(alias = "gst_query_parse_allocation")]
1251    pub fn get(&self) -> (Option<&crate::CapsRef>, bool) {
1252        unsafe {
1253            let mut caps = ptr::null_mut();
1254            let mut need_pool = mem::MaybeUninit::uninit();
1255
1256            ffi::gst_query_parse_allocation(self.as_mut_ptr(), &mut caps, need_pool.as_mut_ptr());
1257            (
1258                if caps.is_null() {
1259                    None
1260                } else {
1261                    Some(crate::CapsRef::from_ptr(caps))
1262                },
1263                from_glib(need_pool.assume_init()),
1264            )
1265        }
1266    }
1267
1268    #[doc(alias = "gst_query_parse_allocation")]
1269    pub fn get_owned(&self) -> (Option<crate::Caps>, bool) {
1270        unsafe {
1271            let (caps, need_pool) = self.get();
1272            (caps.map(|caps| from_glib_none(caps.as_ptr())), need_pool)
1273        }
1274    }
1275
1276    #[doc(alias = "gst_allocation_params")]
1277    #[doc(alias = "gst_query_get_n_allocation_params")]
1278    #[doc(alias = "gst_query_parse_nth_allocation_param")]
1279    pub fn allocation_params(&self) -> AllocationParamsIter<'_> {
1280        AllocationParamsIter::new(self)
1281    }
1282
1283    #[doc(alias = "get_allocation_pools")]
1284    #[doc(alias = "gst_query_get_n_allocation_pools")]
1285    #[doc(alias = "gst_query_parse_nth_allocation_pool")]
1286    pub fn allocation_pools(&self) -> AllocationPoolsIter<'_> {
1287        AllocationPoolsIter::new(self)
1288    }
1289
1290    #[doc(alias = "get_allocation_metas")]
1291    #[doc(alias = "gst_query_get_n_allocation_metas")]
1292    #[doc(alias = "gst_query_parse_nth_allocation_meta")]
1293    pub fn allocation_metas(&self) -> AllocationMetasIter<'_> {
1294        AllocationMetasIter::new(self)
1295    }
1296
1297    #[doc(alias = "gst_query_find_allocation_meta")]
1298    pub fn find_allocation_meta<U: crate::MetaAPI>(&self) -> Option<u32> {
1299        unsafe {
1300            let mut idx = mem::MaybeUninit::uninit();
1301            if ffi::gst_query_find_allocation_meta(
1302                self.as_mut_ptr(),
1303                U::meta_api().into_glib(),
1304                idx.as_mut_ptr(),
1305            ) != glib::ffi::GFALSE
1306            {
1307                Some(idx.assume_init())
1308            } else {
1309                None
1310            }
1311        }
1312    }
1313
1314    #[doc(alias = "gst_query_add_allocation_pool")]
1315    pub fn add_allocation_pool(
1316        &mut self,
1317        pool: Option<&impl IsA<crate::BufferPool>>,
1318        size: u32,
1319        min_buffers: u32,
1320        max_buffers: u32,
1321    ) {
1322        unsafe {
1323            ffi::gst_query_add_allocation_pool(
1324                self.as_mut_ptr(),
1325                pool.to_glib_none().0 as *mut ffi::GstBufferPool,
1326                size,
1327                min_buffers,
1328                max_buffers,
1329            );
1330        }
1331    }
1332
1333    #[doc(alias = "gst_query_set_nth_allocation_pool")]
1334    pub fn set_nth_allocation_pool(
1335        &mut self,
1336        idx: u32,
1337        pool: Option<&impl IsA<crate::BufferPool>>,
1338        size: u32,
1339        min_buffers: u32,
1340        max_buffers: u32,
1341    ) {
1342        unsafe {
1343            let n = ffi::gst_query_get_n_allocation_pools(self.as_mut_ptr());
1344            assert!(idx < n);
1345            ffi::gst_query_set_nth_allocation_pool(
1346                self.as_mut_ptr(),
1347                idx,
1348                pool.to_glib_none().0 as *mut ffi::GstBufferPool,
1349                size,
1350                min_buffers,
1351                max_buffers,
1352            );
1353        }
1354    }
1355
1356    #[doc(alias = "gst_query_remove_nth_allocation_pool")]
1357    pub fn remove_nth_allocation_pool(&mut self, idx: u32) {
1358        unsafe {
1359            let n = ffi::gst_query_get_n_allocation_pools(self.as_mut_ptr());
1360            assert!(idx < n);
1361            ffi::gst_query_remove_nth_allocation_pool(self.as_mut_ptr(), idx);
1362        }
1363    }
1364
1365    #[doc(alias = "gst_query_add_allocation_param")]
1366    pub fn add_allocation_param(
1367        &mut self,
1368        allocator: Option<&impl IsA<crate::Allocator>>,
1369        params: crate::AllocationParams,
1370    ) {
1371        unsafe {
1372            ffi::gst_query_add_allocation_param(
1373                self.as_mut_ptr(),
1374                allocator.to_glib_none().0 as *mut ffi::GstAllocator,
1375                params.as_ptr(),
1376            );
1377        }
1378    }
1379
1380    #[doc(alias = "gst_query_set_nth_allocation_param")]
1381    pub fn set_nth_allocation_param(
1382        &mut self,
1383        idx: u32,
1384        allocator: Option<&impl IsA<crate::Allocator>>,
1385        params: crate::AllocationParams,
1386    ) {
1387        unsafe {
1388            let n = ffi::gst_query_get_n_allocation_params(self.as_mut_ptr());
1389            assert!(idx < n);
1390            ffi::gst_query_set_nth_allocation_param(
1391                self.as_mut_ptr(),
1392                idx,
1393                allocator.to_glib_none().0 as *mut ffi::GstAllocator,
1394                params.as_ptr(),
1395            );
1396        }
1397    }
1398
1399    #[doc(alias = "gst_query_remove_nth_allocation_param")]
1400    pub fn remove_nth_allocation_param(&mut self, idx: u32) {
1401        unsafe {
1402            let n = ffi::gst_query_get_n_allocation_params(self.as_mut_ptr());
1403            assert!(idx < n);
1404            ffi::gst_query_remove_nth_allocation_param(self.as_mut_ptr(), idx);
1405        }
1406    }
1407
1408    #[doc(alias = "gst_query_add_allocation_meta")]
1409    pub fn add_allocation_meta<U: crate::MetaAPI>(
1410        &mut self,
1411        structure: Option<&crate::StructureRef>,
1412    ) {
1413        unsafe {
1414            ffi::gst_query_add_allocation_meta(
1415                self.as_mut_ptr(),
1416                U::meta_api().into_glib(),
1417                if let Some(structure) = structure {
1418                    structure.as_ptr()
1419                } else {
1420                    ptr::null()
1421                },
1422            );
1423        }
1424    }
1425
1426    #[doc(alias = "gst_query_remove_nth_allocation_meta")]
1427    pub fn remove_nth_allocation_meta(&mut self, idx: u32) {
1428        unsafe {
1429            let n = ffi::gst_query_get_n_allocation_metas(self.as_mut_ptr());
1430            assert!(idx < n);
1431            ffi::gst_query_remove_nth_allocation_meta(self.as_mut_ptr(), idx);
1432        }
1433    }
1434}
1435
1436impl std::fmt::Debug for Allocation {
1437    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1438        let (caps, need_pool) = self.get();
1439
1440        struct AllocationParamsDebug<'a>(&'a Allocation);
1441
1442        impl std::fmt::Debug for AllocationParamsDebug<'_> {
1443            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1444                f.debug_list().entries(self.0.allocation_params()).finish()
1445            }
1446        }
1447
1448        struct AllocationPoolsDebug<'a>(&'a Allocation);
1449
1450        impl std::fmt::Debug for AllocationPoolsDebug<'_> {
1451            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1452                f.debug_list().entries(self.0.allocation_pools()).finish()
1453            }
1454        }
1455
1456        struct AllocationMetasDebug<'a>(&'a Allocation);
1457
1458        impl std::fmt::Debug for AllocationMetasDebug<'_> {
1459            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1460                f.debug_list().entries(self.0.allocation_metas()).finish()
1461            }
1462        }
1463
1464        f.debug_struct("Allocation")
1465            .field("structure", &self.query().structure())
1466            .field("caps", &caps)
1467            .field("need-pool", &need_pool)
1468            .field("allocation-params", &AllocationParamsDebug(self))
1469            .field("allocation-pools", &AllocationPoolsDebug(self))
1470            .field("allocation-metas", &AllocationMetasDebug(self))
1471            .finish()
1472    }
1473}
1474
1475impl std::fmt::Debug for Allocation<Query> {
1476    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1477        Allocation::<QueryRef>::fmt(self, f)
1478    }
1479}
1480
1481crate::utils::define_fixed_size_iter!(
1482    AllocationParamsIter,
1483    &'a Allocation,
1484    (Option<crate::Allocator>, crate::AllocationParams),
1485    |collection: &Allocation| unsafe {
1486        ffi::gst_query_get_n_allocation_params(collection.as_mut_ptr()) as usize
1487    },
1488    |collection: &Allocation, idx: usize| unsafe {
1489        let mut allocator = ptr::null_mut();
1490        let mut p = mem::MaybeUninit::uninit();
1491        ffi::gst_query_parse_nth_allocation_param(
1492            collection.as_mut_ptr(),
1493            idx as u32,
1494            &mut allocator,
1495            p.as_mut_ptr(),
1496        );
1497        (from_glib_full(allocator), from_glib(p.assume_init()))
1498    }
1499);
1500
1501crate::utils::define_fixed_size_iter!(
1502    AllocationPoolsIter,
1503    &'a Allocation,
1504    (Option<crate::BufferPool>, u32, u32, u32),
1505    |collection: &Allocation| unsafe {
1506        ffi::gst_query_get_n_allocation_pools(collection.as_mut_ptr()) as usize
1507    },
1508    |collection: &Allocation, idx: usize| unsafe {
1509        let mut pool = ptr::null_mut();
1510        let mut size = mem::MaybeUninit::uninit();
1511        let mut min_buffers = mem::MaybeUninit::uninit();
1512        let mut max_buffers = mem::MaybeUninit::uninit();
1513
1514        ffi::gst_query_parse_nth_allocation_pool(
1515            collection.as_mut_ptr(),
1516            idx as u32,
1517            &mut pool,
1518            size.as_mut_ptr(),
1519            min_buffers.as_mut_ptr(),
1520            max_buffers.as_mut_ptr(),
1521        );
1522
1523        (
1524            from_glib_full(pool),
1525            size.assume_init(),
1526            min_buffers.assume_init(),
1527            max_buffers.assume_init(),
1528        )
1529    }
1530);
1531
1532crate::utils::define_fixed_size_iter!(
1533    AllocationMetasIter,
1534    &'a Allocation,
1535    (glib::Type, Option<&'a crate::StructureRef>),
1536    |collection: &Allocation| unsafe {
1537        ffi::gst_query_get_n_allocation_metas(collection.as_mut_ptr()) as usize
1538    },
1539    |collection: &Allocation, idx: usize| unsafe {
1540        let mut structure = ptr::null();
1541
1542        let api = ffi::gst_query_parse_nth_allocation_meta(
1543            collection.as_mut_ptr(),
1544            idx as u32,
1545            &mut structure,
1546        );
1547
1548        (
1549            from_glib(api),
1550            if structure.is_null() {
1551                None
1552            } else {
1553                Some(crate::StructureRef::from_glib_borrow(structure))
1554            },
1555        )
1556    }
1557);
1558
1559declare_concrete_query!(Scheduling, T);
1560impl Scheduling<Query> {
1561    #[doc(alias = "gst_query_new_scheduling")]
1562    pub fn new() -> Self {
1563        assert_initialized_main_thread!();
1564        unsafe { Self(from_glib_full(ffi::gst_query_new_scheduling())) }
1565    }
1566}
1567
1568impl Default for Scheduling<Query> {
1569    fn default() -> Self {
1570        Self::new()
1571    }
1572}
1573
1574impl Scheduling {
1575    #[doc(alias = "gst_query_has_scheduling_mode")]
1576    pub fn has_scheduling_mode(&self, mode: crate::PadMode) -> bool {
1577        unsafe {
1578            from_glib(ffi::gst_query_has_scheduling_mode(
1579                self.as_mut_ptr(),
1580                mode.into_glib(),
1581            ))
1582        }
1583    }
1584
1585    #[doc(alias = "gst_query_has_scheduling_mode_with_flags")]
1586    pub fn has_scheduling_mode_with_flags(
1587        &self,
1588        mode: crate::PadMode,
1589        flags: crate::SchedulingFlags,
1590    ) -> bool {
1591        skip_assert_initialized!();
1592        unsafe {
1593            from_glib(ffi::gst_query_has_scheduling_mode_with_flags(
1594                self.as_mut_ptr(),
1595                mode.into_glib(),
1596                flags.into_glib(),
1597            ))
1598        }
1599    }
1600
1601    #[doc(alias = "get_scheduling_modes")]
1602    #[doc(alias = "gst_query_get_n_scheduling_modes")]
1603    pub fn scheduling_modes(&self) -> PadModesIter<'_> {
1604        PadModesIter::new(self)
1605    }
1606
1607    #[doc(alias = "get_result")]
1608    #[doc(alias = "gst_query_parse_scheduling")]
1609    pub fn result(&self) -> (crate::SchedulingFlags, i32, i32, i32) {
1610        unsafe {
1611            let mut flags = mem::MaybeUninit::uninit();
1612            let mut minsize = mem::MaybeUninit::uninit();
1613            let mut maxsize = mem::MaybeUninit::uninit();
1614            let mut align = mem::MaybeUninit::uninit();
1615
1616            ffi::gst_query_parse_scheduling(
1617                self.as_mut_ptr(),
1618                flags.as_mut_ptr(),
1619                minsize.as_mut_ptr(),
1620                maxsize.as_mut_ptr(),
1621                align.as_mut_ptr(),
1622            );
1623
1624            (
1625                from_glib(flags.assume_init()),
1626                minsize.assume_init(),
1627                maxsize.assume_init(),
1628                align.assume_init(),
1629            )
1630        }
1631    }
1632
1633    #[doc(alias = "gst_query_add_scheduling_mode")]
1634    pub fn add_scheduling_modes(&mut self, modes: impl IntoIterator<Item = crate::PadMode>) {
1635        unsafe {
1636            for mode in modes.into_iter() {
1637                ffi::gst_query_add_scheduling_mode(self.as_mut_ptr(), mode.into_glib());
1638            }
1639        }
1640    }
1641
1642    #[doc(alias = "gst_query_set_scheduling")]
1643    pub fn set(&mut self, flags: crate::SchedulingFlags, minsize: i32, maxsize: i32, align: i32) {
1644        unsafe {
1645            ffi::gst_query_set_scheduling(
1646                self.as_mut_ptr(),
1647                flags.into_glib(),
1648                minsize,
1649                maxsize,
1650                align,
1651            );
1652        }
1653    }
1654}
1655
1656impl std::fmt::Debug for Scheduling {
1657    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1658        struct PadModesDebug<'a>(&'a Scheduling);
1659
1660        impl std::fmt::Debug for PadModesDebug<'_> {
1661            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1662                f.debug_list().entries(self.0.scheduling_modes()).finish()
1663            }
1664        }
1665
1666        f.debug_struct("Scheduling")
1667            .field("structure", &self.query().structure())
1668            .field("result", &self.result())
1669            .field("scheduling-modes", &PadModesDebug(self))
1670            .finish()
1671    }
1672}
1673
1674impl std::fmt::Debug for Scheduling<Query> {
1675    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1676        Scheduling::<QueryRef>::fmt(self, f)
1677    }
1678}
1679
1680crate::utils::define_fixed_size_iter!(
1681    PadModesIter,
1682    &'a Scheduling,
1683    crate::PadMode,
1684    |collection: &Scheduling| unsafe {
1685        ffi::gst_query_get_n_scheduling_modes(collection.as_mut_ptr()) as usize
1686    },
1687    |collection: &Scheduling, idx: usize| unsafe {
1688        from_glib(ffi::gst_query_parse_nth_scheduling_mode(
1689            collection.as_mut_ptr(),
1690            idx as u32,
1691        ))
1692    }
1693);
1694
1695declare_concrete_query!(AcceptCaps, T);
1696impl AcceptCaps<Query> {
1697    #[doc(alias = "gst_query_new_accept_caps")]
1698    pub fn new(caps: &crate::Caps) -> Self {
1699        skip_assert_initialized!();
1700        unsafe {
1701            Self(from_glib_full(ffi::gst_query_new_accept_caps(
1702                caps.as_mut_ptr(),
1703            )))
1704        }
1705    }
1706}
1707
1708impl AcceptCaps {
1709    #[doc(alias = "get_caps")]
1710    #[doc(alias = "gst_query_parse_accept_caps")]
1711    pub fn caps(&self) -> &crate::CapsRef {
1712        unsafe {
1713            let mut caps = ptr::null_mut();
1714            ffi::gst_query_parse_accept_caps(self.as_mut_ptr(), &mut caps);
1715            crate::CapsRef::from_ptr(caps)
1716        }
1717    }
1718
1719    #[doc(alias = "get_caps_owned")]
1720    #[doc(alias = "gst_query_parse_accept_caps")]
1721    pub fn caps_owned(&self) -> crate::Caps {
1722        unsafe { from_glib_none(self.caps().as_ptr()) }
1723    }
1724
1725    #[doc(alias = "get_result")]
1726    #[doc(alias = "gst_query_parse_accept_caps_result")]
1727    pub fn result(&self) -> bool {
1728        unsafe {
1729            let mut accepted = mem::MaybeUninit::uninit();
1730            ffi::gst_query_parse_accept_caps_result(self.as_mut_ptr(), accepted.as_mut_ptr());
1731            from_glib(accepted.assume_init())
1732        }
1733    }
1734
1735    #[doc(alias = "gst_query_set_accept_caps_result")]
1736    pub fn set_result(&mut self, accepted: bool) {
1737        unsafe {
1738            ffi::gst_query_set_accept_caps_result(self.as_mut_ptr(), accepted.into_glib());
1739        }
1740    }
1741}
1742
1743impl std::fmt::Debug for AcceptCaps {
1744    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1745        f.debug_struct("AcceptCaps")
1746            .field("structure", &self.query().structure())
1747            .field("result", &self.result())
1748            .field("caps", &self.caps())
1749            .finish()
1750    }
1751}
1752
1753impl std::fmt::Debug for AcceptCaps<Query> {
1754    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1755        AcceptCaps::<QueryRef>::fmt(self, f)
1756    }
1757}
1758
1759declare_concrete_query!(Caps, T);
1760impl Caps<Query> {
1761    #[doc(alias = "gst_query_new_caps")]
1762    pub fn new(filter: Option<&crate::Caps>) -> Self {
1763        skip_assert_initialized!();
1764        unsafe {
1765            Self(from_glib_full(ffi::gst_query_new_caps(
1766                filter.to_glib_none().0,
1767            )))
1768        }
1769    }
1770}
1771
1772impl Caps {
1773    #[doc(alias = "get_filter")]
1774    #[doc(alias = "gst_query_parse_caps")]
1775    pub fn filter(&self) -> Option<&crate::CapsRef> {
1776        unsafe {
1777            let mut caps = ptr::null_mut();
1778            ffi::gst_query_parse_caps(self.as_mut_ptr(), &mut caps);
1779            if caps.is_null() {
1780                None
1781            } else {
1782                Some(crate::CapsRef::from_ptr(caps))
1783            }
1784        }
1785    }
1786
1787    #[doc(alias = "get_filter_owned")]
1788    #[doc(alias = "gst_query_parse_caps")]
1789    pub fn filter_owned(&self) -> Option<crate::Caps> {
1790        unsafe { self.filter().map(|caps| from_glib_none(caps.as_ptr())) }
1791    }
1792
1793    #[doc(alias = "get_result")]
1794    #[doc(alias = "gst_query_parse_caps_result")]
1795    pub fn result(&self) -> Option<&crate::CapsRef> {
1796        unsafe {
1797            let mut caps = ptr::null_mut();
1798            ffi::gst_query_parse_caps_result(self.as_mut_ptr(), &mut caps);
1799            if caps.is_null() {
1800                None
1801            } else {
1802                Some(crate::CapsRef::from_ptr(caps))
1803            }
1804        }
1805    }
1806
1807    #[doc(alias = "get_result_owned")]
1808    #[doc(alias = "gst_query_parse_caps_result")]
1809    pub fn result_owned(&self) -> Option<crate::Caps> {
1810        unsafe { self.result().map(|caps| from_glib_none(caps.as_ptr())) }
1811    }
1812
1813    #[doc(alias = "gst_query_set_caps_result")]
1814    pub fn set_result<'a>(&mut self, caps: impl Into<Option<&'a crate::Caps>>) {
1815        unsafe {
1816            ffi::gst_query_set_caps_result(
1817                self.as_mut_ptr(),
1818                caps.into()
1819                    .map(|caps| caps.as_mut_ptr())
1820                    .unwrap_or(ptr::null_mut()),
1821            );
1822        }
1823    }
1824}
1825
1826impl std::fmt::Debug for Caps {
1827    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1828        f.debug_struct("Caps")
1829            .field("structure", &self.query().structure())
1830            .field("result", &self.result())
1831            .field("filter", &self.filter())
1832            .finish()
1833    }
1834}
1835
1836impl std::fmt::Debug for Caps<Query> {
1837    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1838        Caps::<QueryRef>::fmt(self, f)
1839    }
1840}
1841
1842declare_concrete_query!(Drain, T);
1843impl Drain<Query> {
1844    #[doc(alias = "gst_query_new_drain")]
1845    pub fn new() -> Self {
1846        assert_initialized_main_thread!();
1847        unsafe { Self(from_glib_full(ffi::gst_query_new_drain())) }
1848    }
1849}
1850
1851impl Default for Drain<Query> {
1852    fn default() -> Self {
1853        Self::new()
1854    }
1855}
1856
1857impl std::fmt::Debug for Drain {
1858    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1859        f.debug_struct("Drain")
1860            .field("structure", &self.query().structure())
1861            .finish()
1862    }
1863}
1864
1865impl std::fmt::Debug for Drain<Query> {
1866    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1867        Drain::<QueryRef>::fmt(self, f)
1868    }
1869}
1870
1871declare_concrete_query!(Context, T);
1872impl Context<Query> {
1873    #[doc(alias = "gst_query_new_context")]
1874    pub fn new(context_type: &str) -> Self {
1875        assert_initialized_main_thread!();
1876        unsafe {
1877            Self(from_glib_full(ffi::gst_query_new_context(
1878                context_type.to_glib_none().0,
1879            )))
1880        }
1881    }
1882}
1883
1884impl Context {
1885    #[doc(alias = "get_context")]
1886    #[doc(alias = "gst_query_parse_context")]
1887    pub fn context(&self) -> Option<&crate::ContextRef> {
1888        unsafe {
1889            let mut context = ptr::null_mut();
1890            ffi::gst_query_parse_context(self.as_mut_ptr(), &mut context);
1891            if context.is_null() {
1892                None
1893            } else {
1894                Some(crate::ContextRef::from_ptr(context))
1895            }
1896        }
1897    }
1898
1899    #[doc(alias = "get_context_owned")]
1900    #[doc(alias = "gst_query_parse_context")]
1901    pub fn context_owned(&self) -> Option<crate::Context> {
1902        unsafe {
1903            self.context()
1904                .map(|context| from_glib_none(context.as_ptr()))
1905        }
1906    }
1907
1908    #[doc(alias = "get_context_type")]
1909    #[doc(alias = "gst_query_parse_context_type")]
1910    pub fn context_type(&self) -> &str {
1911        unsafe {
1912            let mut context_type = ptr::null();
1913            ffi::gst_query_parse_context_type(self.as_mut_ptr(), &mut context_type);
1914            CStr::from_ptr(context_type).to_str().unwrap()
1915        }
1916    }
1917
1918    #[doc(alias = "gst_query_set_context")]
1919    pub fn set_context<'a>(&mut self, context: impl Into<Option<&'a crate::Context>>) {
1920        unsafe {
1921            ffi::gst_query_set_context(
1922                self.as_mut_ptr(),
1923                context
1924                    .into()
1925                    .map(|context| context.as_mut_ptr())
1926                    .unwrap_or(ptr::null_mut()),
1927            );
1928        }
1929    }
1930}
1931
1932impl std::fmt::Debug for Context {
1933    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1934        f.debug_struct("Context")
1935            .field("structure", &self.query().structure())
1936            .field("context", &self.context())
1937            .field("context-type", &self.context_type())
1938            .finish()
1939    }
1940}
1941
1942impl std::fmt::Debug for Context<Query> {
1943    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1944        Context::<QueryRef>::fmt(self, f)
1945    }
1946}
1947
1948#[cfg(feature = "v1_16")]
1949#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1950declare_concrete_query!(Bitrate, T);
1951
1952#[cfg(feature = "v1_16")]
1953#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1954impl Bitrate<Query> {
1955    #[doc(alias = "gst_query_new_bitrate")]
1956    pub fn new() -> Self {
1957        assert_initialized_main_thread!();
1958        unsafe { Self(from_glib_full(ffi::gst_query_new_bitrate())) }
1959    }
1960}
1961
1962#[cfg(feature = "v1_16")]
1963#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1964impl Default for Bitrate<Query> {
1965    fn default() -> Self {
1966        Self::new()
1967    }
1968}
1969
1970#[cfg(feature = "v1_16")]
1971#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1972impl Bitrate {
1973    #[doc(alias = "get_bitrate")]
1974    #[doc(alias = "gst_query_parse_bitrate")]
1975    pub fn bitrate(&self) -> u32 {
1976        unsafe {
1977            let mut bitrate = mem::MaybeUninit::uninit();
1978            ffi::gst_query_parse_bitrate(self.as_mut_ptr(), bitrate.as_mut_ptr());
1979            bitrate.assume_init()
1980        }
1981    }
1982
1983    #[doc(alias = "gst_query_set_bitrate")]
1984    pub fn set_bitrate(&mut self, bitrate: u32) {
1985        unsafe {
1986            ffi::gst_query_set_bitrate(self.as_mut_ptr(), bitrate);
1987        }
1988    }
1989}
1990
1991#[cfg(feature = "v1_16")]
1992impl std::fmt::Debug for Bitrate {
1993    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1994        f.debug_struct("Bitrate")
1995            .field("structure", &self.query().structure())
1996            .field("bitrate", &self.bitrate())
1997            .finish()
1998    }
1999}
2000
2001#[cfg(feature = "v1_16")]
2002impl std::fmt::Debug for Bitrate<Query> {
2003    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2004        Bitrate::<QueryRef>::fmt(self, f)
2005    }
2006}
2007
2008#[cfg(feature = "v1_22")]
2009#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2010declare_concrete_query!(Selectable, T);
2011
2012#[cfg(feature = "v1_22")]
2013#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2014impl Selectable<Query> {
2015    #[doc(alias = "gst_query_new_selectable")]
2016    pub fn new() -> Self {
2017        assert_initialized_main_thread!();
2018        unsafe { Self(from_glib_full(ffi::gst_query_new_selectable())) }
2019    }
2020}
2021
2022#[cfg(feature = "v1_22")]
2023#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2024impl Default for Selectable<Query> {
2025    fn default() -> Self {
2026        Self::new()
2027    }
2028}
2029
2030#[cfg(feature = "v1_22")]
2031#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2032impl Selectable {
2033    #[doc(alias = "get_selectable")]
2034    #[doc(alias = "gst_query_parse_selectable")]
2035    pub fn selectable(&self) -> bool {
2036        unsafe {
2037            let mut selectable = mem::MaybeUninit::uninit();
2038            ffi::gst_query_parse_selectable(self.as_mut_ptr(), selectable.as_mut_ptr());
2039            from_glib(selectable.assume_init())
2040        }
2041    }
2042
2043    #[doc(alias = "gst_query_set_selectable")]
2044    pub fn set_selectable(&mut self, selectable: bool) {
2045        unsafe {
2046            ffi::gst_query_set_selectable(self.as_mut_ptr(), selectable.into_glib());
2047        }
2048    }
2049}
2050
2051#[cfg(feature = "v1_22")]
2052impl std::fmt::Debug for Selectable {
2053    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2054        f.debug_struct("Selectable")
2055            .field("structure", &self.query().structure())
2056            .field("selectable", &self.selectable())
2057            .finish()
2058    }
2059}
2060
2061#[cfg(feature = "v1_22")]
2062impl std::fmt::Debug for Selectable<Query> {
2063    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2064        Selectable::<QueryRef>::fmt(self, f)
2065    }
2066}
2067
2068declare_concrete_query!(Other, T);
2069
2070impl std::fmt::Debug for Other {
2071    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2072        f.debug_struct("Other")
2073            .field("structure", &self.query().structure())
2074            .finish()
2075    }
2076}
2077
2078impl std::fmt::Debug for Other<Query> {
2079    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2080        Other::<QueryRef>::fmt(self, f)
2081    }
2082}
2083
2084#[cfg(test)]
2085mod tests {
2086    use super::*;
2087    use crate::ClockTime;
2088
2089    #[test]
2090    fn test_writability() {
2091        crate::init().unwrap();
2092
2093        fn check_mut(query: &mut QueryRef) {
2094            skip_assert_initialized!();
2095            match query.view_mut() {
2096                QueryViewMut::Position(p) => {
2097                    let pos = p.result();
2098                    assert_eq!(pos.try_into(), Ok(ClockTime::NONE));
2099                    p.set(Some(3 * ClockTime::SECOND));
2100                    let pos = p.result();
2101                    assert_eq!(pos.try_into(), Ok(Some(3 * ClockTime::SECOND)));
2102                }
2103                _ => panic!("Wrong concrete Query in Query"),
2104            }
2105        }
2106
2107        fn check_ref(query: &QueryRef) {
2108            skip_assert_initialized!();
2109            match query.view() {
2110                QueryView::Position(p) => {
2111                    let pos = p.result();
2112                    assert_eq!(pos.try_into(), Ok(Some(3 * ClockTime::SECOND)));
2113                    assert!(!p.as_mut_ptr().is_null());
2114                }
2115                _ => panic!("Wrong concrete Query in Query"),
2116            }
2117        }
2118
2119        let mut p = Position::new(crate::Format::Time);
2120        let pos = p.result();
2121        assert_eq!(pos.try_into(), Ok(ClockTime::NONE));
2122
2123        p.structure_mut().set("check_mut", true);
2124
2125        // deref
2126        assert!(!p.is_serialized());
2127
2128        {
2129            check_mut(&mut p);
2130
2131            let structure = p.structure();
2132            structure.unwrap().has_field("check_mut");
2133
2134            // Expected: cannot borrow `p` as mutable because it is also borrowed as immutable
2135            //check_mut(&mut p);
2136        }
2137
2138        check_ref(&p);
2139    }
2140
2141    #[test]
2142    fn test_into_query() {
2143        crate::init().unwrap();
2144        let d = Duration::new(crate::Format::Time);
2145
2146        let mut query: Query = d.into();
2147        assert!(query.is_writable());
2148
2149        let query = query.make_mut();
2150        if let QueryViewMut::Duration(d) = query.view_mut() {
2151            d.set(Some(2 * ClockTime::SECOND));
2152        }
2153
2154        if let QueryView::Duration(d) = query.view() {
2155            let duration = d.result();
2156            assert_eq!(duration.try_into(), Ok(Some(2 * ClockTime::SECOND)));
2157        }
2158    }
2159
2160    #[test]
2161    fn test_concrete_to_sys() {
2162        crate::init().unwrap();
2163
2164        let p = Position::new(crate::Format::Time);
2165        assert!(!p.as_mut_ptr().is_null());
2166    }
2167
2168    #[test]
2169    fn allocation_need_pool() {
2170        crate::init().unwrap();
2171
2172        let mut a = Allocation::new(Some(&crate::Caps::new_empty_simple("foo/bar")), true);
2173        let pool = crate::BufferPool::new();
2174        a.add_allocation_pool(Some(&pool), 1024, 1, 4);
2175    }
2176
2177    #[test]
2178    fn allocation_do_not_need_pool() {
2179        crate::init().unwrap();
2180
2181        let mut a = Allocation::new(Some(&crate::Caps::new_empty_simple("foo/bar")), false);
2182        a.add_allocation_pool(crate::BufferPool::NONE, 1024, 1, 4);
2183
2184        // cannot infer type of the type parameter `T` declared on the enum `Option`
2185        //a.add_allocation_pool(None, 1024, 1, 4);
2186
2187        // This would be possible if we moved the `crate::BufferPool`
2188        // as a generic argument instead of using current arg type:
2189        // - `pool: Option<&impl IsA<crate::BufferPool>>`
2190        //a.add_allocation_pool::<crate::BufferPool>(None, 1024, 1, 4);
2191    }
2192
2193    #[test]
2194    fn set_uri() {
2195        crate::init().unwrap();
2196
2197        let mut uri_q = Uri::new();
2198        uri_q.set_uri("https://test.org");
2199        uri_q.set_uri(&String::from("https://test.org"));
2200
2201        uri_q.set_uri(Some("https://test.org"));
2202        uri_q.set_uri(Some(&String::from("https://test.org")));
2203
2204        // FIXME: this is commented out for now due to an inconsistent
2205        //        assertion in `GStreamer` which results in critical logs.
2206        /*
2207        let none: Option<&str> = None;
2208        uri_q.set_uri(none);
2209
2210        let none: Option<String> = None;
2211        uri_q.set_uri(none.as_ref());
2212
2213        uri_q.set_uri::<str>(None);
2214        */
2215    }
2216
2217    #[test]
2218    fn query_type() {
2219        crate::init().unwrap();
2220
2221        assert!(!QueryType::Allocation.is_upstream());
2222        assert!(QueryType::Allocation.is_downstream());
2223        assert!(QueryType::Allocation.is_serialized());
2224
2225        assert!(QueryType::Latency.is_upstream());
2226        assert!(QueryType::Latency.is_downstream());
2227        assert!(!QueryType::Latency.is_serialized());
2228
2229        assert!(QueryType::Scheduling.is_upstream());
2230        assert!(!QueryType::Scheduling.is_downstream());
2231        assert!(!QueryType::Scheduling.is_serialized());
2232
2233        let lat = Latency::new();
2234        assert_eq!(lat.type_(), QueryType::Latency);
2235    }
2236}