Skip to main content

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