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 = "get_result")]
502    #[doc(alias = "gst_query_parse_latency")]
503    pub fn result_struct(&self) -> LatencyResult {
504        let (is_live, min, max) = self.result();
505
506        LatencyResult { is_live, min, max }
507    }
508
509    #[doc(alias = "gst_query_set_latency")]
510    pub fn set(
511        &mut self,
512        live: bool,
513        min: crate::ClockTime,
514        max: impl Into<Option<crate::ClockTime>>,
515    ) {
516        unsafe {
517            ffi::gst_query_set_latency(
518                self.as_mut_ptr(),
519                live.into_glib(),
520                min.into_glib(),
521                max.into().into_glib(),
522            );
523        }
524    }
525}
526
527#[derive(Debug)]
528pub struct LatencyResult {
529    pub is_live: bool,
530    pub min: crate::ClockTime,
531    pub max: Option<crate::ClockTime>,
532}
533
534impl std::fmt::Debug for Latency {
535    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
536        f.debug_struct("Latency")
537            .field("structure", &self.query().structure())
538            .field("result", &self.result())
539            .finish()
540    }
541}
542
543impl std::fmt::Debug for Latency<Query> {
544    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
545        Latency::<QueryRef>::fmt(self, f)
546    }
547}
548
549declare_concrete_query!(Seeking, T);
550impl Seeking<Query> {
551    #[doc(alias = "gst_query_new_seeking")]
552    pub fn new(fmt: crate::Format) -> Self {
553        assert_initialized_main_thread!();
554        unsafe { Self(from_glib_full(ffi::gst_query_new_seeking(fmt.into_glib()))) }
555    }
556}
557
558impl Seeking {
559    #[doc(alias = "get_result")]
560    #[doc(alias = "gst_query_parse_seeking")]
561    pub fn result(&self) -> (bool, GenericFormattedValue, GenericFormattedValue) {
562        unsafe {
563            let mut fmt = mem::MaybeUninit::uninit();
564            let mut seekable = mem::MaybeUninit::uninit();
565            let mut start = mem::MaybeUninit::uninit();
566            let mut end = mem::MaybeUninit::uninit();
567            ffi::gst_query_parse_seeking(
568                self.as_mut_ptr(),
569                fmt.as_mut_ptr(),
570                seekable.as_mut_ptr(),
571                start.as_mut_ptr(),
572                end.as_mut_ptr(),
573            );
574
575            (
576                from_glib(seekable.assume_init()),
577                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
578                GenericFormattedValue::new(from_glib(fmt.assume_init()), end.assume_init()),
579            )
580        }
581    }
582
583    #[doc(alias = "get_result")]
584    #[doc(alias = "gst_query_parse_seeking")]
585    pub fn result_struct(&self) -> SeekingResult {
586        let (seekable, start, end) = self.result();
587
588        SeekingResult {
589            seekable,
590            start,
591            end,
592        }
593    }
594
595    #[doc(alias = "get_format")]
596    #[doc(alias = "gst_query_parse_seeking")]
597    pub fn format(&self) -> crate::Format {
598        unsafe {
599            let mut fmt = mem::MaybeUninit::uninit();
600            ffi::gst_query_parse_seeking(
601                self.as_mut_ptr(),
602                fmt.as_mut_ptr(),
603                ptr::null_mut(),
604                ptr::null_mut(),
605                ptr::null_mut(),
606            );
607
608            from_glib(fmt.assume_init())
609        }
610    }
611
612    #[doc(alias = "gst_query_set_seeking")]
613    pub fn set<V: FormattedValue>(
614        &mut self,
615        seekable: bool,
616        start: V,
617        end: impl CompatibleFormattedValue<V>,
618    ) {
619        assert_eq!(self.format(), start.format());
620        let end = end.try_into_checked(start).unwrap();
621
622        unsafe {
623            ffi::gst_query_set_seeking(
624                self.as_mut_ptr(),
625                start.format().into_glib(),
626                seekable.into_glib(),
627                start.into_raw_value(),
628                end.into_raw_value(),
629            );
630        }
631    }
632}
633
634#[derive(Debug)]
635pub struct SeekingResult {
636    pub seekable: bool,
637    pub start: GenericFormattedValue,
638    pub end: GenericFormattedValue,
639}
640
641impl std::fmt::Debug for Seeking {
642    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
643        f.debug_struct("Seeking")
644            .field("structure", &self.query().structure())
645            .field("result", &self.result())
646            .field("format", &self.format())
647            .finish()
648    }
649}
650
651impl std::fmt::Debug for Seeking<Query> {
652    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
653        Seeking::<QueryRef>::fmt(self, f)
654    }
655}
656
657declare_concrete_query!(Segment, T);
658impl Segment<Query> {
659    #[doc(alias = "gst_query_new_segment")]
660    pub fn new(fmt: crate::Format) -> Self {
661        assert_initialized_main_thread!();
662        unsafe { Self(from_glib_full(ffi::gst_query_new_segment(fmt.into_glib()))) }
663    }
664}
665
666impl Segment {
667    #[doc(alias = "get_result")]
668    #[doc(alias = "gst_query_parse_segment")]
669    pub fn result(&self) -> (f64, GenericFormattedValue, GenericFormattedValue) {
670        unsafe {
671            let mut rate = mem::MaybeUninit::uninit();
672            let mut fmt = mem::MaybeUninit::uninit();
673            let mut start = mem::MaybeUninit::uninit();
674            let mut stop = mem::MaybeUninit::uninit();
675
676            ffi::gst_query_parse_segment(
677                self.as_mut_ptr(),
678                rate.as_mut_ptr(),
679                fmt.as_mut_ptr(),
680                start.as_mut_ptr(),
681                stop.as_mut_ptr(),
682            );
683            (
684                rate.assume_init(),
685                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
686                GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
687            )
688        }
689    }
690
691    #[doc(alias = "get_result")]
692    #[doc(alias = "gst_query_parse_segment")]
693    pub fn result_struct(&self) -> SegmentResult {
694        let res = self.result();
695
696        SegmentResult {
697            rate: res.0,
698            start: res.1,
699            stop: res.2,
700        }
701    }
702
703    #[doc(alias = "get_format")]
704    #[doc(alias = "gst_query_parse_segment")]
705    pub fn format(&self) -> crate::Format {
706        unsafe {
707            let mut fmt = mem::MaybeUninit::uninit();
708
709            ffi::gst_query_parse_segment(
710                self.as_mut_ptr(),
711                ptr::null_mut(),
712                fmt.as_mut_ptr(),
713                ptr::null_mut(),
714                ptr::null_mut(),
715            );
716            from_glib(fmt.assume_init())
717        }
718    }
719
720    #[doc(alias = "gst_query_set_segment")]
721    pub fn set<V: FormattedValue>(
722        &mut self,
723        rate: f64,
724        start: V,
725        stop: impl CompatibleFormattedValue<V>,
726    ) {
727        let stop = stop.try_into_checked(start).unwrap();
728
729        unsafe {
730            ffi::gst_query_set_segment(
731                self.as_mut_ptr(),
732                rate,
733                start.format().into_glib(),
734                start.into_raw_value(),
735                stop.into_raw_value(),
736            );
737        }
738    }
739}
740
741#[derive(Debug)]
742pub struct SegmentResult {
743    pub rate: f64,
744    pub start: GenericFormattedValue,
745    pub stop: GenericFormattedValue,
746}
747
748impl std::fmt::Debug for Segment {
749    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
750        f.debug_struct("Segment")
751            .field("structure", &self.query().structure())
752            .field("result", &self.result())
753            .field("format", &self.format())
754            .finish()
755    }
756}
757
758impl std::fmt::Debug for Segment<Query> {
759    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
760        Segment::<QueryRef>::fmt(self, f)
761    }
762}
763
764declare_concrete_query!(Convert, T);
765impl Convert<Query> {
766    #[doc(alias = "gst_query_new_convert")]
767    pub fn new(value: impl FormattedValue, dest_fmt: crate::Format) -> Self {
768        assert_initialized_main_thread!();
769        unsafe {
770            Self(from_glib_full(ffi::gst_query_new_convert(
771                value.format().into_glib(),
772                value.into_raw_value(),
773                dest_fmt.into_glib(),
774            )))
775        }
776    }
777}
778
779impl Convert {
780    #[doc(alias = "get_result")]
781    #[doc(alias = "gst_query_parse_convert")]
782    pub fn result(&self) -> (GenericFormattedValue, GenericFormattedValue) {
783        unsafe {
784            let mut src_fmt = mem::MaybeUninit::uninit();
785            let mut src = mem::MaybeUninit::uninit();
786            let mut dest_fmt = mem::MaybeUninit::uninit();
787            let mut dest = mem::MaybeUninit::uninit();
788
789            ffi::gst_query_parse_convert(
790                self.as_mut_ptr(),
791                src_fmt.as_mut_ptr(),
792                src.as_mut_ptr(),
793                dest_fmt.as_mut_ptr(),
794                dest.as_mut_ptr(),
795            );
796            (
797                GenericFormattedValue::new(from_glib(src_fmt.assume_init()), src.assume_init()),
798                GenericFormattedValue::new(from_glib(dest_fmt.assume_init()), dest.assume_init()),
799            )
800        }
801    }
802
803    #[doc(alias = "get_result")]
804    #[doc(alias = "gst_query_parse_convert")]
805    pub fn result_struct(&self) -> ConvertResult {
806        let (src, dest) = self.result();
807
808        ConvertResult { src, dest }
809    }
810
811    #[doc(alias = "gst_query_parse_convert")]
812    pub fn get(&self) -> (GenericFormattedValue, crate::Format) {
813        unsafe {
814            let mut src_fmt = mem::MaybeUninit::uninit();
815            let mut src = mem::MaybeUninit::uninit();
816            let mut dest_fmt = mem::MaybeUninit::uninit();
817
818            ffi::gst_query_parse_convert(
819                self.as_mut_ptr(),
820                src_fmt.as_mut_ptr(),
821                src.as_mut_ptr(),
822                dest_fmt.as_mut_ptr(),
823                ptr::null_mut(),
824            );
825            (
826                GenericFormattedValue::new(from_glib(src_fmt.assume_init()), src.assume_init()),
827                from_glib(dest_fmt.assume_init()),
828            )
829        }
830    }
831
832    #[doc(alias = "gst_query_set_convert")]
833    pub fn set(&mut self, src: impl FormattedValue, dest: impl FormattedValue) {
834        unsafe {
835            ffi::gst_query_set_convert(
836                self.as_mut_ptr(),
837                src.format().into_glib(),
838                src.into_raw_value(),
839                dest.format().into_glib(),
840                dest.into_raw_value(),
841            );
842        }
843    }
844}
845
846#[derive(Debug)]
847pub struct ConvertResult {
848    pub src: GenericFormattedValue,
849    pub dest: GenericFormattedValue,
850}
851
852impl std::fmt::Debug for Convert {
853    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
854        let (source, dest) = self.result();
855
856        f.debug_struct("Convert")
857            .field("structure", &self.query().structure())
858            .field("source", &source)
859            .field("dest", &dest)
860            .finish()
861    }
862}
863
864impl std::fmt::Debug for Convert<Query> {
865    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
866        Convert::<QueryRef>::fmt(self, f)
867    }
868}
869
870declare_concrete_query!(Formats, T);
871impl Formats<Query> {
872    #[doc(alias = "gst_query_new_formats")]
873    pub fn new() -> Self {
874        assert_initialized_main_thread!();
875        unsafe { Self(from_glib_full(ffi::gst_query_new_formats())) }
876    }
877}
878
879impl Default for Formats<Query> {
880    fn default() -> Self {
881        Self::new()
882    }
883}
884
885impl Formats {
886    #[doc(alias = "get_result")]
887    #[doc(alias = "gst_query_parse_n_formats")]
888    #[doc(alias = "gst_query_parse_nth_format")]
889    pub fn result(&self) -> FormatsIter<'_> {
890        FormatsIter::new(self)
891    }
892
893    #[doc(alias = "gst_query_set_formats")]
894    #[doc(alias = "gst_query_set_formatsv")]
895    pub fn set(&mut self, formats: impl IntoIterator<Item = crate::Format>) {
896        unsafe {
897            let v = formats
898                .into_iter()
899                .map(|f| f.into_glib())
900                .collect::<SmallVec<[_; 8]>>();
901            ffi::gst_query_set_formatsv(self.as_mut_ptr(), v.len() as i32, v.as_ptr() as *mut _);
902        }
903    }
904}
905
906impl std::fmt::Debug for Formats {
907    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
908        struct FormatsDebug<'a>(&'a Formats);
909
910        impl std::fmt::Debug for FormatsDebug<'_> {
911            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
912                f.debug_list().entries(self.0.result()).finish()
913            }
914        }
915
916        f.debug_struct("Formats")
917            .field("structure", &self.query().structure())
918            .field("result", &FormatsDebug(self))
919            .finish()
920    }
921}
922
923impl std::fmt::Debug for Formats<Query> {
924    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
925        Formats::<QueryRef>::fmt(self, f)
926    }
927}
928
929crate::utils::define_fixed_size_iter!(
930    FormatsIter,
931    &'a Formats,
932    crate::Format,
933    |collection: &Formats| unsafe {
934        let mut n = mem::MaybeUninit::uninit();
935        ffi::gst_query_parse_n_formats(collection.as_mut_ptr(), n.as_mut_ptr());
936        n.assume_init() as usize
937    },
938    |collection: &Formats, idx: usize| unsafe {
939        let mut fmt = mem::MaybeUninit::uninit();
940        ffi::gst_query_parse_nth_format(collection.as_mut_ptr(), idx as u32, fmt.as_mut_ptr());
941        from_glib(fmt.assume_init())
942    }
943);
944
945declare_concrete_query!(Buffering, T);
946impl Buffering<Query> {
947    #[doc(alias = "gst_query_new_buffering")]
948    pub fn new(fmt: crate::Format) -> Self {
949        assert_initialized_main_thread!();
950        unsafe {
951            Self(from_glib_full(ffi::gst_query_new_buffering(
952                fmt.into_glib(),
953            )))
954        }
955    }
956}
957
958impl Buffering {
959    #[doc(alias = "get_format")]
960    #[doc(alias = "gst_query_parse_buffering_range")]
961    pub fn format(&self) -> crate::Format {
962        unsafe {
963            let mut fmt = mem::MaybeUninit::uninit();
964
965            ffi::gst_query_parse_buffering_range(
966                self.as_mut_ptr(),
967                fmt.as_mut_ptr(),
968                ptr::null_mut(),
969                ptr::null_mut(),
970                ptr::null_mut(),
971            );
972
973            from_glib(fmt.assume_init())
974        }
975    }
976
977    #[doc(alias = "get_percent")]
978    #[doc(alias = "gst_query_parse_buffering_percent")]
979    pub fn percent(&self) -> (bool, i32) {
980        unsafe {
981            let mut busy = mem::MaybeUninit::uninit();
982            let mut percent = mem::MaybeUninit::uninit();
983
984            ffi::gst_query_parse_buffering_percent(
985                self.as_mut_ptr(),
986                busy.as_mut_ptr(),
987                percent.as_mut_ptr(),
988            );
989
990            (from_glib(busy.assume_init()), percent.assume_init())
991        }
992    }
993
994    #[doc(alias = "get_percent")]
995    #[doc(alias = "gst_query_parse_buffering_percent")]
996    pub fn percent_struct(&self) -> BufferingPercent {
997        let (is_busy, percent) = self.percent();
998
999        BufferingPercent {
1000            is_busy,
1001            precent: unsafe { try_from_glib(percent as i64).ok() },
1002        }
1003    }
1004
1005    #[doc(alias = "get_range")]
1006    #[doc(alias = "gst_query_parse_buffering_range")]
1007    pub fn range(&self) -> (GenericFormattedValue, GenericFormattedValue, i64) {
1008        unsafe {
1009            let mut fmt = mem::MaybeUninit::uninit();
1010            let mut start = mem::MaybeUninit::uninit();
1011            let mut stop = mem::MaybeUninit::uninit();
1012            let mut estimated_total = mem::MaybeUninit::uninit();
1013
1014            ffi::gst_query_parse_buffering_range(
1015                self.as_mut_ptr(),
1016                fmt.as_mut_ptr(),
1017                start.as_mut_ptr(),
1018                stop.as_mut_ptr(),
1019                estimated_total.as_mut_ptr(),
1020            );
1021            (
1022                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
1023                GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
1024                estimated_total.assume_init(),
1025            )
1026        }
1027    }
1028
1029    #[doc(alias = "get_range")]
1030    #[doc(alias = "gst_query_parse_buffering_range")]
1031    pub fn range_struct(&self) -> BufferingRange {
1032        let (start, stop, estimated_total) = self.range();
1033
1034        BufferingRange {
1035            start,
1036            stop,
1037            estimated_total: unsafe {
1038                try_from_glib(estimated_total)
1039                    .ok()
1040                    .map(|ct: crate::ClockTime| *crate::ClockTime::MSECOND * ct)
1041            },
1042        }
1043    }
1044
1045    #[doc(alias = "get_stats")]
1046    #[doc(alias = "gst_query_parse_buffering_stats")]
1047    pub fn stats(&self) -> (crate::BufferingMode, i32, i32, i64) {
1048        unsafe {
1049            let mut mode = mem::MaybeUninit::uninit();
1050            let mut avg_in = mem::MaybeUninit::uninit();
1051            let mut avg_out = mem::MaybeUninit::uninit();
1052            let mut buffering_left = mem::MaybeUninit::uninit();
1053
1054            ffi::gst_query_parse_buffering_stats(
1055                self.as_mut_ptr(),
1056                mode.as_mut_ptr(),
1057                avg_in.as_mut_ptr(),
1058                avg_out.as_mut_ptr(),
1059                buffering_left.as_mut_ptr(),
1060            );
1061
1062            (
1063                from_glib(mode.assume_init()),
1064                avg_in.assume_init(),
1065                avg_out.assume_init(),
1066                buffering_left.assume_init(),
1067            )
1068        }
1069    }
1070
1071    #[doc(alias = "get_stats")]
1072    #[doc(alias = "gst_query_parse_buffering_stats")]
1073    pub fn stats_struct(&self) -> BufferingStats {
1074        let (mode, avg_in, avg_out, buffering_left) = self.stats();
1075
1076        BufferingStats {
1077            mode,
1078            avg_in,
1079            avg_out,
1080            buffering_left: unsafe {
1081                try_from_glib(buffering_left)
1082                    .ok()
1083                    .map(|ct: crate::ClockTime| *crate::ClockTime::MSECOND * ct)
1084            },
1085        }
1086    }
1087
1088    #[doc(alias = "get_ranges")]
1089    #[doc(alias = "gst_query_get_n_buffering_ranges")]
1090    #[doc(alias = "gst_query_parse_nth_buffering_range")]
1091    pub fn ranges(&self) -> RangesIter<'_> {
1092        RangesIter::new(self)
1093    }
1094
1095    #[doc(alias = "gst_query_set_buffering_percent")]
1096    pub fn set_percent(&mut self, busy: bool, percent: i32) {
1097        unsafe {
1098            ffi::gst_query_set_buffering_percent(self.as_mut_ptr(), busy.into_glib(), percent);
1099        }
1100    }
1101
1102    #[doc(alias = "gst_query_set_buffering_range")]
1103    pub fn set_range<V: FormattedValue>(
1104        &mut self,
1105        start: V,
1106        stop: impl CompatibleFormattedValue<V>,
1107        estimated_total: i64,
1108    ) {
1109        assert_eq!(self.format(), start.format());
1110        let stop = stop.try_into_checked(start).unwrap();
1111
1112        unsafe {
1113            ffi::gst_query_set_buffering_range(
1114                self.as_mut_ptr(),
1115                start.format().into_glib(),
1116                start.into_raw_value(),
1117                stop.into_raw_value(),
1118                estimated_total,
1119            );
1120        }
1121    }
1122
1123    #[doc(alias = "gst_query_set_buffering_stats")]
1124    pub fn set_stats(
1125        &mut self,
1126        mode: crate::BufferingMode,
1127        avg_in: i32,
1128        avg_out: i32,
1129        buffering_left: i64,
1130    ) {
1131        skip_assert_initialized!();
1132        unsafe {
1133            ffi::gst_query_set_buffering_stats(
1134                self.as_mut_ptr(),
1135                mode.into_glib(),
1136                avg_in,
1137                avg_out,
1138                buffering_left,
1139            );
1140        }
1141    }
1142
1143    #[doc(alias = "gst_query_add_buffering_range")]
1144    pub fn add_buffering_ranges<V: FormattedValue, U: CompatibleFormattedValue<V> + Copy>(
1145        &mut self,
1146        ranges: impl IntoIterator<Item = (V, U)>,
1147    ) {
1148        unsafe {
1149            let fmt = self.format();
1150
1151            for (start, stop) in ranges.into_iter() {
1152                assert_eq!(start.format(), fmt);
1153                let stop = stop.try_into_checked(start).unwrap();
1154                ffi::gst_query_add_buffering_range(
1155                    self.as_mut_ptr(),
1156                    start.into_raw_value(),
1157                    stop.into_raw_value(),
1158                );
1159            }
1160        }
1161    }
1162}
1163
1164#[derive(Debug)]
1165pub struct BufferingPercent {
1166    pub is_busy: bool,
1167    pub precent: Option<crate::format::Percent>,
1168}
1169
1170#[derive(Debug)]
1171pub struct BufferingRange {
1172    pub start: GenericFormattedValue,
1173    pub stop: GenericFormattedValue,
1174    pub estimated_total: Option<crate::ClockTime>,
1175}
1176
1177#[derive(Debug)]
1178pub struct BufferingStats {
1179    pub mode: crate::BufferingMode,
1180    pub avg_in: i32,
1181    pub avg_out: i32,
1182    pub buffering_left: Option<crate::ClockTime>,
1183}
1184
1185impl std::fmt::Debug for Buffering {
1186    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1187        struct RangesDebug<'a>(&'a Buffering);
1188
1189        impl std::fmt::Debug for RangesDebug<'_> {
1190            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1191                f.debug_list().entries(self.0.ranges()).finish()
1192            }
1193        }
1194
1195        f.debug_struct("Buffering")
1196            .field("structure", &self.query().structure())
1197            .field("format", &self.format())
1198            .field("percent", &self.percent())
1199            .field("range", &RangesDebug(self))
1200            .finish()
1201    }
1202}
1203
1204impl std::fmt::Debug for Buffering<Query> {
1205    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1206        Buffering::<QueryRef>::fmt(self, f)
1207    }
1208}
1209
1210crate::utils::define_fixed_size_iter!(
1211    RangesIter,
1212    &'a Buffering,
1213    (GenericFormattedValue, GenericFormattedValue),
1214    |collection: &Buffering| unsafe {
1215        ffi::gst_query_get_n_buffering_ranges(collection.as_mut_ptr()) as usize
1216    },
1217    |collection: &Buffering, idx: usize| unsafe {
1218        let mut fmt = mem::MaybeUninit::uninit();
1219        ffi::gst_query_parse_buffering_range(
1220            collection.as_mut_ptr(),
1221            fmt.as_mut_ptr(),
1222            ptr::null_mut(),
1223            ptr::null_mut(),
1224            ptr::null_mut(),
1225        );
1226        let fmt = from_glib(fmt.assume_init());
1227
1228        let mut start = mem::MaybeUninit::uninit();
1229        let mut stop = mem::MaybeUninit::uninit();
1230        ffi::gst_query_parse_nth_buffering_range(
1231            collection.as_mut_ptr(),
1232            idx as u32,
1233            start.as_mut_ptr(),
1234            stop.as_mut_ptr(),
1235        );
1236
1237        (
1238            GenericFormattedValue::new(fmt, start.assume_init()),
1239            GenericFormattedValue::new(fmt, stop.assume_init()),
1240        )
1241    }
1242);
1243
1244declare_concrete_query!(Custom, T);
1245impl Custom<Query> {
1246    #[doc(alias = "gst_query_new_custom")]
1247    pub fn new(structure: crate::Structure) -> Self {
1248        skip_assert_initialized!();
1249        unsafe {
1250            Self(from_glib_full(ffi::gst_query_new_custom(
1251                ffi::GST_QUERY_CUSTOM,
1252                structure.into_glib_ptr(),
1253            )))
1254        }
1255    }
1256}
1257
1258impl std::fmt::Debug for Custom {
1259    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1260        f.debug_struct("Custom")
1261            .field("structure", &self.query().structure())
1262            .finish()
1263    }
1264}
1265
1266impl std::fmt::Debug for Custom<Query> {
1267    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1268        Custom::<QueryRef>::fmt(self, f)
1269    }
1270}
1271
1272declare_concrete_query!(Uri, T);
1273impl Uri<Query> {
1274    #[doc(alias = "gst_query_new_uri")]
1275    pub fn new() -> Self {
1276        assert_initialized_main_thread!();
1277        unsafe { Self(from_glib_full(ffi::gst_query_new_uri())) }
1278    }
1279}
1280
1281impl Default for Uri<Query> {
1282    fn default() -> Self {
1283        Self::new()
1284    }
1285}
1286
1287impl Uri {
1288    #[doc(alias = "get_uri")]
1289    #[doc(alias = "gst_query_parse_uri")]
1290    pub fn uri(&self) -> Option<glib::GString> {
1291        unsafe {
1292            let mut uri = ptr::null_mut();
1293            ffi::gst_query_parse_uri(self.as_mut_ptr(), &mut uri);
1294            from_glib_full(uri)
1295        }
1296    }
1297
1298    #[doc(alias = "get_redirection")]
1299    #[doc(alias = "gst_query_parse_uri_redirection")]
1300    #[doc(alias = "gst_query_parse_uri_redirection_permanent")]
1301    pub fn redirection(&self) -> (Option<glib::GString>, bool) {
1302        unsafe {
1303            let mut uri = ptr::null_mut();
1304            ffi::gst_query_parse_uri_redirection(self.as_mut_ptr(), &mut uri);
1305            let mut permanent = mem::MaybeUninit::uninit();
1306            ffi::gst_query_parse_uri_redirection_permanent(
1307                self.as_mut_ptr(),
1308                permanent.as_mut_ptr(),
1309            );
1310
1311            (from_glib_full(uri), from_glib(permanent.assume_init()))
1312        }
1313    }
1314
1315    #[doc(alias = "get_redirection")]
1316    #[doc(alias = "gst_query_parse_uri_redirection")]
1317    #[doc(alias = "gst_query_parse_uri_redirection_permanent")]
1318    pub fn uri_redirection(&self) -> Option<glib::GString> {
1319        self.redirection().0
1320    }
1321
1322    #[doc(alias = "get_redirection")]
1323    #[doc(alias = "gst_query_parse_uri_redirection")]
1324    #[doc(alias = "gst_query_parse_uri_redirection_permanent")]
1325    pub fn uri_redirection_permanent(&self) -> bool {
1326        self.redirection().1
1327    }
1328
1329    #[doc(alias = "gst_query_set_uri")]
1330    pub fn set_uri<'a, T>(&mut self, uri: impl Into<Option<&'a T>>)
1331    where
1332        T: 'a + AsRef<str> + ?Sized,
1333    {
1334        unsafe {
1335            ffi::gst_query_set_uri(
1336                self.as_mut_ptr(),
1337                uri.into().map(AsRef::as_ref).to_glib_none().0,
1338            );
1339        }
1340    }
1341
1342    #[doc(alias = "gst_query_set_uri_redirection")]
1343    #[doc(alias = "gst_query_set_uri_redirection_permanent")]
1344    pub fn set_redirection<'a, T>(&mut self, uri: impl Into<Option<&'a T>>, permanent: bool)
1345    where
1346        T: 'a + AsRef<str> + ?Sized,
1347    {
1348        unsafe {
1349            ffi::gst_query_set_uri_redirection(
1350                self.as_mut_ptr(),
1351                uri.into().map(AsRef::as_ref).to_glib_none().0,
1352            );
1353            ffi::gst_query_set_uri_redirection_permanent(
1354                self.0.as_mut_ptr(),
1355                permanent.into_glib(),
1356            );
1357        }
1358    }
1359}
1360
1361impl std::fmt::Debug for Uri {
1362    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1363        let (redirection, permanent) = self.redirection();
1364        f.debug_struct("Uri")
1365            .field("structure", &self.query().structure())
1366            .field("uri", &self.uri())
1367            .field("redirection", &redirection)
1368            .field("redirection-permanent", &permanent)
1369            .finish()
1370    }
1371}
1372
1373impl std::fmt::Debug for Uri<Query> {
1374    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1375        Uri::<QueryRef>::fmt(self, f)
1376    }
1377}
1378
1379declare_concrete_query!(Allocation, T);
1380impl Allocation<Query> {
1381    #[doc(alias = "gst_query_new_allocation")]
1382    pub fn new(caps: Option<&crate::Caps>, need_pool: bool) -> Self {
1383        skip_assert_initialized!();
1384        unsafe {
1385            Self(from_glib_full(ffi::gst_query_new_allocation(
1386                caps.map(|caps| caps.as_mut_ptr())
1387                    .unwrap_or(ptr::null_mut()),
1388                need_pool.into_glib(),
1389            )))
1390        }
1391    }
1392}
1393
1394impl Allocation {
1395    #[doc(alias = "gst_query_parse_allocation")]
1396    pub fn get(&self) -> (Option<&crate::CapsRef>, bool) {
1397        unsafe {
1398            let mut caps = ptr::null_mut();
1399            let mut need_pool = mem::MaybeUninit::uninit();
1400
1401            ffi::gst_query_parse_allocation(self.as_mut_ptr(), &mut caps, need_pool.as_mut_ptr());
1402            (
1403                if caps.is_null() {
1404                    None
1405                } else {
1406                    Some(crate::CapsRef::from_ptr(caps))
1407                },
1408                from_glib(need_pool.assume_init()),
1409            )
1410        }
1411    }
1412
1413    #[doc(alias = "gst_query_parse_allocation")]
1414    pub fn caps(&self) -> Option<&crate::CapsRef> {
1415        self.get().0
1416    }
1417
1418    #[doc(alias = "gst_query_parse_allocation")]
1419    pub fn need_pool(&self) -> bool {
1420        self.get().1
1421    }
1422
1423    #[doc(alias = "gst_query_parse_allocation")]
1424    pub fn get_owned(&self) -> (Option<crate::Caps>, bool) {
1425        unsafe {
1426            let (caps, need_pool) = self.get();
1427            (caps.map(|caps| from_glib_none(caps.as_ptr())), need_pool)
1428        }
1429    }
1430
1431    #[doc(alias = "gst_allocation_params")]
1432    #[doc(alias = "gst_query_get_n_allocation_params")]
1433    #[doc(alias = "gst_query_parse_nth_allocation_param")]
1434    pub fn allocation_params(&self) -> AllocationParamsIter<'_> {
1435        AllocationParamsIter::new(self)
1436    }
1437
1438    #[doc(alias = "get_allocation_pools")]
1439    #[doc(alias = "gst_query_get_n_allocation_pools")]
1440    #[doc(alias = "gst_query_parse_nth_allocation_pool")]
1441    pub fn allocation_pools(&self) -> AllocationPoolsIter<'_> {
1442        AllocationPoolsIter::new(self)
1443    }
1444
1445    #[doc(alias = "get_allocation_metas")]
1446    #[doc(alias = "gst_query_get_n_allocation_metas")]
1447    #[doc(alias = "gst_query_parse_nth_allocation_meta")]
1448    pub fn allocation_metas(&self) -> AllocationMetasIter<'_> {
1449        AllocationMetasIter::new(self)
1450    }
1451
1452    #[doc(alias = "gst_query_find_allocation_meta")]
1453    pub fn find_allocation_meta<U: crate::MetaAPI>(&self) -> Option<u32> {
1454        unsafe {
1455            let mut idx = mem::MaybeUninit::uninit();
1456            if ffi::gst_query_find_allocation_meta(
1457                self.as_mut_ptr(),
1458                U::meta_api().into_glib(),
1459                idx.as_mut_ptr(),
1460            ) != glib::ffi::GFALSE
1461            {
1462                Some(idx.assume_init())
1463            } else {
1464                None
1465            }
1466        }
1467    }
1468
1469    #[doc(alias = "gst_query_add_allocation_pool")]
1470    pub fn add_allocation_pool(
1471        &mut self,
1472        pool: Option<&impl IsA<crate::BufferPool>>,
1473        size: u32,
1474        min_buffers: u32,
1475        max_buffers: u32,
1476    ) {
1477        unsafe {
1478            ffi::gst_query_add_allocation_pool(
1479                self.as_mut_ptr(),
1480                pool.to_glib_none().0 as *mut ffi::GstBufferPool,
1481                size,
1482                min_buffers,
1483                max_buffers,
1484            );
1485        }
1486    }
1487
1488    #[doc(alias = "gst_query_set_nth_allocation_pool")]
1489    pub fn set_nth_allocation_pool(
1490        &mut self,
1491        idx: u32,
1492        pool: Option<&impl IsA<crate::BufferPool>>,
1493        size: u32,
1494        min_buffers: u32,
1495        max_buffers: u32,
1496    ) {
1497        unsafe {
1498            let n = ffi::gst_query_get_n_allocation_pools(self.as_mut_ptr());
1499            assert!(idx < n);
1500            ffi::gst_query_set_nth_allocation_pool(
1501                self.as_mut_ptr(),
1502                idx,
1503                pool.to_glib_none().0 as *mut ffi::GstBufferPool,
1504                size,
1505                min_buffers,
1506                max_buffers,
1507            );
1508        }
1509    }
1510
1511    #[doc(alias = "gst_query_remove_nth_allocation_pool")]
1512    pub fn remove_nth_allocation_pool(&mut self, idx: u32) {
1513        unsafe {
1514            let n = ffi::gst_query_get_n_allocation_pools(self.as_mut_ptr());
1515            assert!(idx < n);
1516            ffi::gst_query_remove_nth_allocation_pool(self.as_mut_ptr(), idx);
1517        }
1518    }
1519
1520    #[doc(alias = "gst_query_add_allocation_param")]
1521    pub fn add_allocation_param(
1522        &mut self,
1523        allocator: Option<&impl IsA<crate::Allocator>>,
1524        params: crate::AllocationParams,
1525    ) {
1526        unsafe {
1527            ffi::gst_query_add_allocation_param(
1528                self.as_mut_ptr(),
1529                allocator.to_glib_none().0 as *mut ffi::GstAllocator,
1530                params.as_ptr(),
1531            );
1532        }
1533    }
1534
1535    #[doc(alias = "gst_query_set_nth_allocation_param")]
1536    pub fn set_nth_allocation_param(
1537        &mut self,
1538        idx: u32,
1539        allocator: Option<&impl IsA<crate::Allocator>>,
1540        params: crate::AllocationParams,
1541    ) {
1542        unsafe {
1543            let n = ffi::gst_query_get_n_allocation_params(self.as_mut_ptr());
1544            assert!(idx < n);
1545            ffi::gst_query_set_nth_allocation_param(
1546                self.as_mut_ptr(),
1547                idx,
1548                allocator.to_glib_none().0 as *mut ffi::GstAllocator,
1549                params.as_ptr(),
1550            );
1551        }
1552    }
1553
1554    #[doc(alias = "gst_query_remove_nth_allocation_param")]
1555    pub fn remove_nth_allocation_param(&mut self, idx: u32) {
1556        unsafe {
1557            let n = ffi::gst_query_get_n_allocation_params(self.as_mut_ptr());
1558            assert!(idx < n);
1559            ffi::gst_query_remove_nth_allocation_param(self.as_mut_ptr(), idx);
1560        }
1561    }
1562
1563    #[doc(alias = "gst_query_add_allocation_meta")]
1564    pub fn add_allocation_meta<U: crate::MetaAPI>(
1565        &mut self,
1566        structure: Option<&crate::StructureRef>,
1567    ) {
1568        unsafe {
1569            ffi::gst_query_add_allocation_meta(
1570                self.as_mut_ptr(),
1571                U::meta_api().into_glib(),
1572                if let Some(structure) = structure {
1573                    structure.as_ptr()
1574                } else {
1575                    ptr::null()
1576                },
1577            );
1578        }
1579    }
1580
1581    #[doc(alias = "gst_query_remove_nth_allocation_meta")]
1582    pub fn remove_nth_allocation_meta(&mut self, idx: u32) {
1583        unsafe {
1584            let n = ffi::gst_query_get_n_allocation_metas(self.as_mut_ptr());
1585            assert!(idx < n);
1586            ffi::gst_query_remove_nth_allocation_meta(self.as_mut_ptr(), idx);
1587        }
1588    }
1589}
1590
1591impl std::fmt::Debug for Allocation {
1592    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1593        let (caps, need_pool) = self.get();
1594
1595        struct AllocationParamsDebug<'a>(&'a Allocation);
1596
1597        impl std::fmt::Debug for AllocationParamsDebug<'_> {
1598            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1599                f.debug_list().entries(self.0.allocation_params()).finish()
1600            }
1601        }
1602
1603        struct AllocationPoolsDebug<'a>(&'a Allocation);
1604
1605        impl std::fmt::Debug for AllocationPoolsDebug<'_> {
1606            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1607                f.debug_list().entries(self.0.allocation_pools()).finish()
1608            }
1609        }
1610
1611        struct AllocationMetasDebug<'a>(&'a Allocation);
1612
1613        impl std::fmt::Debug for AllocationMetasDebug<'_> {
1614            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1615                f.debug_list().entries(self.0.allocation_metas()).finish()
1616            }
1617        }
1618
1619        f.debug_struct("Allocation")
1620            .field("structure", &self.query().structure())
1621            .field("caps", &caps)
1622            .field("need-pool", &need_pool)
1623            .field("allocation-params", &AllocationParamsDebug(self))
1624            .field("allocation-pools", &AllocationPoolsDebug(self))
1625            .field("allocation-metas", &AllocationMetasDebug(self))
1626            .finish()
1627    }
1628}
1629
1630impl std::fmt::Debug for Allocation<Query> {
1631    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1632        Allocation::<QueryRef>::fmt(self, f)
1633    }
1634}
1635
1636crate::utils::define_fixed_size_iter!(
1637    AllocationParamsIter,
1638    &'a Allocation,
1639    (Option<crate::Allocator>, crate::AllocationParams),
1640    |collection: &Allocation| unsafe {
1641        ffi::gst_query_get_n_allocation_params(collection.as_mut_ptr()) as usize
1642    },
1643    |collection: &Allocation, idx: usize| unsafe {
1644        let mut allocator = ptr::null_mut();
1645        let mut p = mem::MaybeUninit::uninit();
1646        ffi::gst_query_parse_nth_allocation_param(
1647            collection.as_mut_ptr(),
1648            idx as u32,
1649            &mut allocator,
1650            p.as_mut_ptr(),
1651        );
1652        (from_glib_full(allocator), from_glib(p.assume_init()))
1653    }
1654);
1655
1656crate::utils::define_fixed_size_iter!(
1657    AllocationPoolsIter,
1658    &'a Allocation,
1659    (Option<crate::BufferPool>, u32, u32, u32),
1660    |collection: &Allocation| unsafe {
1661        ffi::gst_query_get_n_allocation_pools(collection.as_mut_ptr()) as usize
1662    },
1663    |collection: &Allocation, idx: usize| unsafe {
1664        let mut pool = ptr::null_mut();
1665        let mut size = mem::MaybeUninit::uninit();
1666        let mut min_buffers = mem::MaybeUninit::uninit();
1667        let mut max_buffers = mem::MaybeUninit::uninit();
1668
1669        ffi::gst_query_parse_nth_allocation_pool(
1670            collection.as_mut_ptr(),
1671            idx as u32,
1672            &mut pool,
1673            size.as_mut_ptr(),
1674            min_buffers.as_mut_ptr(),
1675            max_buffers.as_mut_ptr(),
1676        );
1677
1678        (
1679            from_glib_full(pool),
1680            size.assume_init(),
1681            min_buffers.assume_init(),
1682            max_buffers.assume_init(),
1683        )
1684    }
1685);
1686
1687crate::utils::define_fixed_size_iter!(
1688    AllocationMetasIter,
1689    &'a Allocation,
1690    (glib::Type, Option<&'a crate::StructureRef>),
1691    |collection: &Allocation| unsafe {
1692        ffi::gst_query_get_n_allocation_metas(collection.as_mut_ptr()) as usize
1693    },
1694    |collection: &Allocation, idx: usize| unsafe {
1695        let mut structure = ptr::null();
1696
1697        let api = ffi::gst_query_parse_nth_allocation_meta(
1698            collection.as_mut_ptr(),
1699            idx as u32,
1700            &mut structure,
1701        );
1702
1703        (
1704            from_glib(api),
1705            if structure.is_null() {
1706                None
1707            } else {
1708                Some(crate::StructureRef::from_glib_borrow(structure))
1709            },
1710        )
1711    }
1712);
1713
1714declare_concrete_query!(Scheduling, T);
1715impl Scheduling<Query> {
1716    #[doc(alias = "gst_query_new_scheduling")]
1717    pub fn new() -> Self {
1718        assert_initialized_main_thread!();
1719        unsafe { Self(from_glib_full(ffi::gst_query_new_scheduling())) }
1720    }
1721}
1722
1723impl Default for Scheduling<Query> {
1724    fn default() -> Self {
1725        Self::new()
1726    }
1727}
1728
1729impl Scheduling {
1730    #[doc(alias = "gst_query_has_scheduling_mode")]
1731    pub fn has_scheduling_mode(&self, mode: crate::PadMode) -> bool {
1732        unsafe {
1733            from_glib(ffi::gst_query_has_scheduling_mode(
1734                self.as_mut_ptr(),
1735                mode.into_glib(),
1736            ))
1737        }
1738    }
1739
1740    #[doc(alias = "gst_query_has_scheduling_mode_with_flags")]
1741    pub fn has_scheduling_mode_with_flags(
1742        &self,
1743        mode: crate::PadMode,
1744        flags: crate::SchedulingFlags,
1745    ) -> bool {
1746        skip_assert_initialized!();
1747        unsafe {
1748            from_glib(ffi::gst_query_has_scheduling_mode_with_flags(
1749                self.as_mut_ptr(),
1750                mode.into_glib(),
1751                flags.into_glib(),
1752            ))
1753        }
1754    }
1755
1756    #[doc(alias = "get_scheduling_modes")]
1757    #[doc(alias = "gst_query_get_n_scheduling_modes")]
1758    pub fn scheduling_modes(&self) -> PadModesIter<'_> {
1759        PadModesIter::new(self)
1760    }
1761
1762    #[doc(alias = "get_result")]
1763    #[doc(alias = "gst_query_parse_scheduling")]
1764    pub fn result(&self) -> (crate::SchedulingFlags, i32, i32, i32) {
1765        unsafe {
1766            let mut flags = mem::MaybeUninit::uninit();
1767            let mut minsize = mem::MaybeUninit::uninit();
1768            let mut maxsize = mem::MaybeUninit::uninit();
1769            let mut align = mem::MaybeUninit::uninit();
1770
1771            ffi::gst_query_parse_scheduling(
1772                self.as_mut_ptr(),
1773                flags.as_mut_ptr(),
1774                minsize.as_mut_ptr(),
1775                maxsize.as_mut_ptr(),
1776                align.as_mut_ptr(),
1777            );
1778
1779            (
1780                from_glib(flags.assume_init()),
1781                minsize.assume_init(),
1782                maxsize.assume_init(),
1783                align.assume_init(),
1784            )
1785        }
1786    }
1787
1788    #[doc(alias = "get_result")]
1789    #[doc(alias = "gst_query_parse_scheduling")]
1790    pub fn result_struct(&self) -> SchedulingStruct {
1791        let (flags, min_size, max_size, align) = self.result();
1792
1793        SchedulingStruct {
1794            flags,
1795            min_size,
1796            max_size,
1797            align,
1798        }
1799    }
1800
1801    #[doc(alias = "gst_query_add_scheduling_mode")]
1802    pub fn add_scheduling_modes(&mut self, modes: impl IntoIterator<Item = crate::PadMode>) {
1803        unsafe {
1804            for mode in modes.into_iter() {
1805                ffi::gst_query_add_scheduling_mode(self.as_mut_ptr(), mode.into_glib());
1806            }
1807        }
1808    }
1809
1810    #[doc(alias = "gst_query_set_scheduling")]
1811    pub fn set(&mut self, flags: crate::SchedulingFlags, minsize: i32, maxsize: i32, align: i32) {
1812        unsafe {
1813            ffi::gst_query_set_scheduling(
1814                self.as_mut_ptr(),
1815                flags.into_glib(),
1816                minsize,
1817                maxsize,
1818                align,
1819            );
1820        }
1821    }
1822}
1823
1824impl std::fmt::Debug for Scheduling {
1825    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1826        struct PadModesDebug<'a>(&'a Scheduling);
1827
1828        impl std::fmt::Debug for PadModesDebug<'_> {
1829            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1830                f.debug_list().entries(self.0.scheduling_modes()).finish()
1831            }
1832        }
1833
1834        f.debug_struct("Scheduling")
1835            .field("structure", &self.query().structure())
1836            .field("result", &self.result())
1837            .field("scheduling-modes", &PadModesDebug(self))
1838            .finish()
1839    }
1840}
1841
1842#[derive(Debug)]
1843pub struct SchedulingStruct {
1844    pub flags: crate::SchedulingFlags,
1845    pub min_size: i32,
1846    pub max_size: i32,
1847    pub align: i32,
1848}
1849
1850impl std::fmt::Debug for Scheduling<Query> {
1851    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1852        Scheduling::<QueryRef>::fmt(self, f)
1853    }
1854}
1855
1856crate::utils::define_fixed_size_iter!(
1857    PadModesIter,
1858    &'a Scheduling,
1859    crate::PadMode,
1860    |collection: &Scheduling| unsafe {
1861        ffi::gst_query_get_n_scheduling_modes(collection.as_mut_ptr()) as usize
1862    },
1863    |collection: &Scheduling, idx: usize| unsafe {
1864        from_glib(ffi::gst_query_parse_nth_scheduling_mode(
1865            collection.as_mut_ptr(),
1866            idx as u32,
1867        ))
1868    }
1869);
1870
1871declare_concrete_query!(AcceptCaps, T);
1872impl AcceptCaps<Query> {
1873    #[doc(alias = "gst_query_new_accept_caps")]
1874    pub fn new(caps: &crate::Caps) -> Self {
1875        skip_assert_initialized!();
1876        unsafe {
1877            Self(from_glib_full(ffi::gst_query_new_accept_caps(
1878                caps.as_mut_ptr(),
1879            )))
1880        }
1881    }
1882}
1883
1884impl AcceptCaps {
1885    #[doc(alias = "get_caps")]
1886    #[doc(alias = "gst_query_parse_accept_caps")]
1887    pub fn caps(&self) -> &crate::CapsRef {
1888        unsafe {
1889            let mut caps = ptr::null_mut();
1890            ffi::gst_query_parse_accept_caps(self.as_mut_ptr(), &mut caps);
1891            crate::CapsRef::from_ptr(caps)
1892        }
1893    }
1894
1895    #[doc(alias = "get_caps_owned")]
1896    #[doc(alias = "gst_query_parse_accept_caps")]
1897    pub fn caps_owned(&self) -> crate::Caps {
1898        unsafe { from_glib_none(self.caps().as_ptr()) }
1899    }
1900
1901    #[doc(alias = "get_result")]
1902    #[doc(alias = "gst_query_parse_accept_caps_result")]
1903    pub fn result(&self) -> bool {
1904        unsafe {
1905            let mut accepted = mem::MaybeUninit::uninit();
1906            ffi::gst_query_parse_accept_caps_result(self.as_mut_ptr(), accepted.as_mut_ptr());
1907            from_glib(accepted.assume_init())
1908        }
1909    }
1910
1911    #[doc(alias = "gst_query_set_accept_caps_result")]
1912    pub fn set_result(&mut self, accepted: bool) {
1913        unsafe {
1914            ffi::gst_query_set_accept_caps_result(self.as_mut_ptr(), accepted.into_glib());
1915        }
1916    }
1917}
1918
1919impl std::fmt::Debug for AcceptCaps {
1920    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1921        f.debug_struct("AcceptCaps")
1922            .field("structure", &self.query().structure())
1923            .field("result", &self.result())
1924            .field("caps", &self.caps())
1925            .finish()
1926    }
1927}
1928
1929impl std::fmt::Debug for AcceptCaps<Query> {
1930    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1931        AcceptCaps::<QueryRef>::fmt(self, f)
1932    }
1933}
1934
1935declare_concrete_query!(Caps, T);
1936impl Caps<Query> {
1937    #[doc(alias = "gst_query_new_caps")]
1938    pub fn new(filter: Option<&crate::Caps>) -> Self {
1939        skip_assert_initialized!();
1940        unsafe {
1941            Self(from_glib_full(ffi::gst_query_new_caps(
1942                filter.to_glib_none().0,
1943            )))
1944        }
1945    }
1946}
1947
1948impl Caps {
1949    #[doc(alias = "get_filter")]
1950    #[doc(alias = "gst_query_parse_caps")]
1951    pub fn filter(&self) -> Option<&crate::CapsRef> {
1952        unsafe {
1953            let mut caps = ptr::null_mut();
1954            ffi::gst_query_parse_caps(self.as_mut_ptr(), &mut caps);
1955            if caps.is_null() {
1956                None
1957            } else {
1958                Some(crate::CapsRef::from_ptr(caps))
1959            }
1960        }
1961    }
1962
1963    #[doc(alias = "get_filter_owned")]
1964    #[doc(alias = "gst_query_parse_caps")]
1965    pub fn filter_owned(&self) -> Option<crate::Caps> {
1966        unsafe { self.filter().map(|caps| from_glib_none(caps.as_ptr())) }
1967    }
1968
1969    #[doc(alias = "get_result")]
1970    #[doc(alias = "gst_query_parse_caps_result")]
1971    pub fn result(&self) -> Option<&crate::CapsRef> {
1972        unsafe {
1973            let mut caps = ptr::null_mut();
1974            ffi::gst_query_parse_caps_result(self.as_mut_ptr(), &mut caps);
1975            if caps.is_null() {
1976                None
1977            } else {
1978                Some(crate::CapsRef::from_ptr(caps))
1979            }
1980        }
1981    }
1982
1983    #[doc(alias = "get_result_owned")]
1984    #[doc(alias = "gst_query_parse_caps_result")]
1985    pub fn result_owned(&self) -> Option<crate::Caps> {
1986        unsafe { self.result().map(|caps| from_glib_none(caps.as_ptr())) }
1987    }
1988
1989    #[doc(alias = "gst_query_set_caps_result")]
1990    pub fn set_result<'a>(&mut self, caps: impl Into<Option<&'a crate::Caps>>) {
1991        unsafe {
1992            ffi::gst_query_set_caps_result(
1993                self.as_mut_ptr(),
1994                caps.into()
1995                    .map(|caps| caps.as_mut_ptr())
1996                    .unwrap_or(ptr::null_mut()),
1997            );
1998        }
1999    }
2000}
2001
2002impl std::fmt::Debug for Caps {
2003    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2004        f.debug_struct("Caps")
2005            .field("structure", &self.query().structure())
2006            .field("result", &self.result())
2007            .field("filter", &self.filter())
2008            .finish()
2009    }
2010}
2011
2012impl std::fmt::Debug for Caps<Query> {
2013    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2014        Caps::<QueryRef>::fmt(self, f)
2015    }
2016}
2017
2018declare_concrete_query!(Drain, T);
2019impl Drain<Query> {
2020    #[doc(alias = "gst_query_new_drain")]
2021    pub fn new() -> Self {
2022        assert_initialized_main_thread!();
2023        unsafe { Self(from_glib_full(ffi::gst_query_new_drain())) }
2024    }
2025}
2026
2027impl Default for Drain<Query> {
2028    fn default() -> Self {
2029        Self::new()
2030    }
2031}
2032
2033impl std::fmt::Debug for Drain {
2034    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2035        f.debug_struct("Drain")
2036            .field("structure", &self.query().structure())
2037            .finish()
2038    }
2039}
2040
2041impl std::fmt::Debug for Drain<Query> {
2042    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2043        Drain::<QueryRef>::fmt(self, f)
2044    }
2045}
2046
2047declare_concrete_query!(Context, T);
2048impl Context<Query> {
2049    #[doc(alias = "gst_query_new_context")]
2050    pub fn new(context_type: &str) -> Self {
2051        assert_initialized_main_thread!();
2052        unsafe {
2053            Self(from_glib_full(ffi::gst_query_new_context(
2054                context_type.to_glib_none().0,
2055            )))
2056        }
2057    }
2058}
2059
2060impl Context {
2061    #[doc(alias = "get_context")]
2062    #[doc(alias = "gst_query_parse_context")]
2063    pub fn context(&self) -> Option<&crate::ContextRef> {
2064        unsafe {
2065            let mut context = ptr::null_mut();
2066            ffi::gst_query_parse_context(self.as_mut_ptr(), &mut context);
2067            if context.is_null() {
2068                None
2069            } else {
2070                Some(crate::ContextRef::from_ptr(context))
2071            }
2072        }
2073    }
2074
2075    #[doc(alias = "get_context_owned")]
2076    #[doc(alias = "gst_query_parse_context")]
2077    pub fn context_owned(&self) -> Option<crate::Context> {
2078        unsafe {
2079            self.context()
2080                .map(|context| from_glib_none(context.as_ptr()))
2081        }
2082    }
2083
2084    #[doc(alias = "get_context_type")]
2085    #[doc(alias = "gst_query_parse_context_type")]
2086    pub fn context_type(&self) -> &str {
2087        unsafe {
2088            let mut context_type = ptr::null();
2089            ffi::gst_query_parse_context_type(self.as_mut_ptr(), &mut context_type);
2090            CStr::from_ptr(context_type).to_str().unwrap()
2091        }
2092    }
2093
2094    #[doc(alias = "gst_query_set_context")]
2095    pub fn set_context<'a>(&mut self, context: impl Into<Option<&'a crate::Context>>) {
2096        unsafe {
2097            ffi::gst_query_set_context(
2098                self.as_mut_ptr(),
2099                context
2100                    .into()
2101                    .map(|context| context.as_mut_ptr())
2102                    .unwrap_or(ptr::null_mut()),
2103            );
2104        }
2105    }
2106}
2107
2108impl std::fmt::Debug for Context {
2109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2110        f.debug_struct("Context")
2111            .field("structure", &self.query().structure())
2112            .field("context", &self.context())
2113            .field("context-type", &self.context_type())
2114            .finish()
2115    }
2116}
2117
2118impl std::fmt::Debug for Context<Query> {
2119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2120        Context::<QueryRef>::fmt(self, f)
2121    }
2122}
2123
2124#[cfg(feature = "v1_16")]
2125#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
2126declare_concrete_query!(Bitrate, T);
2127
2128#[cfg(feature = "v1_16")]
2129#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
2130impl Bitrate<Query> {
2131    #[doc(alias = "gst_query_new_bitrate")]
2132    pub fn new() -> Self {
2133        assert_initialized_main_thread!();
2134        unsafe { Self(from_glib_full(ffi::gst_query_new_bitrate())) }
2135    }
2136}
2137
2138#[cfg(feature = "v1_16")]
2139#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
2140impl Default for Bitrate<Query> {
2141    fn default() -> Self {
2142        Self::new()
2143    }
2144}
2145
2146#[cfg(feature = "v1_16")]
2147#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
2148impl Bitrate {
2149    #[doc(alias = "get_bitrate")]
2150    #[doc(alias = "gst_query_parse_bitrate")]
2151    pub fn bitrate(&self) -> u32 {
2152        unsafe {
2153            let mut bitrate = mem::MaybeUninit::uninit();
2154            ffi::gst_query_parse_bitrate(self.as_mut_ptr(), bitrate.as_mut_ptr());
2155            bitrate.assume_init()
2156        }
2157    }
2158
2159    #[doc(alias = "gst_query_set_bitrate")]
2160    pub fn set_bitrate(&mut self, bitrate: u32) {
2161        unsafe {
2162            ffi::gst_query_set_bitrate(self.as_mut_ptr(), bitrate);
2163        }
2164    }
2165}
2166
2167#[cfg(feature = "v1_16")]
2168impl std::fmt::Debug for Bitrate {
2169    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2170        f.debug_struct("Bitrate")
2171            .field("structure", &self.query().structure())
2172            .field("bitrate", &self.bitrate())
2173            .finish()
2174    }
2175}
2176
2177#[cfg(feature = "v1_16")]
2178impl std::fmt::Debug for Bitrate<Query> {
2179    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2180        Bitrate::<QueryRef>::fmt(self, f)
2181    }
2182}
2183
2184#[cfg(feature = "v1_22")]
2185#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2186declare_concrete_query!(Selectable, T);
2187
2188#[cfg(feature = "v1_22")]
2189#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2190impl Selectable<Query> {
2191    #[doc(alias = "gst_query_new_selectable")]
2192    pub fn new() -> Self {
2193        assert_initialized_main_thread!();
2194        unsafe { Self(from_glib_full(ffi::gst_query_new_selectable())) }
2195    }
2196}
2197
2198#[cfg(feature = "v1_22")]
2199#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2200impl Default for Selectable<Query> {
2201    fn default() -> Self {
2202        Self::new()
2203    }
2204}
2205
2206#[cfg(feature = "v1_22")]
2207#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2208impl Selectable {
2209    #[doc(alias = "get_selectable")]
2210    #[doc(alias = "gst_query_parse_selectable")]
2211    pub fn selectable(&self) -> bool {
2212        unsafe {
2213            let mut selectable = mem::MaybeUninit::uninit();
2214            ffi::gst_query_parse_selectable(self.as_mut_ptr(), selectable.as_mut_ptr());
2215            from_glib(selectable.assume_init())
2216        }
2217    }
2218
2219    #[doc(alias = "gst_query_set_selectable")]
2220    pub fn set_selectable(&mut self, selectable: bool) {
2221        unsafe {
2222            ffi::gst_query_set_selectable(self.as_mut_ptr(), selectable.into_glib());
2223        }
2224    }
2225}
2226
2227#[cfg(feature = "v1_22")]
2228impl std::fmt::Debug for Selectable {
2229    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2230        f.debug_struct("Selectable")
2231            .field("structure", &self.query().structure())
2232            .field("selectable", &self.selectable())
2233            .finish()
2234    }
2235}
2236
2237#[cfg(feature = "v1_22")]
2238impl std::fmt::Debug for Selectable<Query> {
2239    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2240        Selectable::<QueryRef>::fmt(self, f)
2241    }
2242}
2243
2244declare_concrete_query!(Other, T);
2245
2246impl std::fmt::Debug for Other {
2247    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2248        f.debug_struct("Other")
2249            .field("structure", &self.query().structure())
2250            .finish()
2251    }
2252}
2253
2254impl std::fmt::Debug for Other<Query> {
2255    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2256        Other::<QueryRef>::fmt(self, f)
2257    }
2258}
2259
2260#[cfg(test)]
2261mod tests {
2262    use super::*;
2263    use crate::ClockTime;
2264
2265    #[test]
2266    fn test_writability() {
2267        crate::init().unwrap();
2268
2269        fn check_mut(query: &mut QueryRef) {
2270            skip_assert_initialized!();
2271            match query.view_mut() {
2272                QueryViewMut::Position(p) => {
2273                    let pos = p.result();
2274                    assert_eq!(pos.try_into(), Ok(ClockTime::NONE));
2275                    p.set(Some(3 * ClockTime::SECOND));
2276                    let pos = p.result();
2277                    assert_eq!(pos.try_into(), Ok(Some(3 * ClockTime::SECOND)));
2278                }
2279                _ => panic!("Wrong concrete Query in Query"),
2280            }
2281        }
2282
2283        fn check_ref(query: &QueryRef) {
2284            skip_assert_initialized!();
2285            match query.view() {
2286                QueryView::Position(p) => {
2287                    let pos = p.result();
2288                    assert_eq!(pos.try_into(), Ok(Some(3 * ClockTime::SECOND)));
2289                    assert!(!p.as_mut_ptr().is_null());
2290                }
2291                _ => panic!("Wrong concrete Query in Query"),
2292            }
2293        }
2294
2295        let mut p = Position::new(crate::Format::Time);
2296        let pos = p.result();
2297        assert_eq!(pos.try_into(), Ok(ClockTime::NONE));
2298
2299        p.structure_mut().set("check_mut", true);
2300
2301        // deref
2302        assert!(!p.is_serialized());
2303
2304        {
2305            check_mut(&mut p);
2306
2307            let structure = p.structure();
2308            structure.unwrap().has_field("check_mut");
2309
2310            // Expected: cannot borrow `p` as mutable because it is also borrowed as immutable
2311            //check_mut(&mut p);
2312        }
2313
2314        check_ref(&p);
2315    }
2316
2317    #[test]
2318    fn test_into_query() {
2319        crate::init().unwrap();
2320        let d = Duration::new(crate::Format::Time);
2321
2322        let mut query: Query = d.into();
2323        assert!(query.is_writable());
2324
2325        let query = query.make_mut();
2326        if let QueryViewMut::Duration(d) = query.view_mut() {
2327            d.set(Some(2 * ClockTime::SECOND));
2328        }
2329
2330        if let QueryView::Duration(d) = query.view() {
2331            let duration = d.result();
2332            assert_eq!(duration.try_into(), Ok(Some(2 * ClockTime::SECOND)));
2333        }
2334    }
2335
2336    #[test]
2337    fn test_concrete_to_sys() {
2338        crate::init().unwrap();
2339
2340        let p = Position::new(crate::Format::Time);
2341        assert!(!p.as_mut_ptr().is_null());
2342    }
2343
2344    #[test]
2345    fn allocation_need_pool() {
2346        crate::init().unwrap();
2347
2348        let mut a = Allocation::new(Some(&crate::Caps::new_empty_simple("foo/bar")), true);
2349        let pool = crate::BufferPool::new();
2350        a.add_allocation_pool(Some(&pool), 1024, 1, 4);
2351    }
2352
2353    #[test]
2354    fn allocation_do_not_need_pool() {
2355        crate::init().unwrap();
2356
2357        let mut a = Allocation::new(Some(&crate::Caps::new_empty_simple("foo/bar")), false);
2358        a.add_allocation_pool(crate::BufferPool::NONE, 1024, 1, 4);
2359
2360        // cannot infer type of the type parameter `T` declared on the enum `Option`
2361        //a.add_allocation_pool(None, 1024, 1, 4);
2362
2363        // This would be possible if we moved the `crate::BufferPool`
2364        // as a generic argument instead of using current arg type:
2365        // - `pool: Option<&impl IsA<crate::BufferPool>>`
2366        //a.add_allocation_pool::<crate::BufferPool>(None, 1024, 1, 4);
2367    }
2368
2369    #[test]
2370    fn set_uri() {
2371        crate::init().unwrap();
2372
2373        let mut uri_q = Uri::new();
2374        uri_q.set_uri("https://test.org");
2375        uri_q.set_uri(&String::from("https://test.org"));
2376
2377        uri_q.set_uri(Some("https://test.org"));
2378        uri_q.set_uri(Some(&String::from("https://test.org")));
2379
2380        // FIXME: this is commented out for now due to an inconsistent
2381        //        assertion in `GStreamer` which results in critical logs.
2382        /*
2383        let none: Option<&str> = None;
2384        uri_q.set_uri(none);
2385
2386        let none: Option<String> = None;
2387        uri_q.set_uri(none.as_ref());
2388
2389        uri_q.set_uri::<str>(None);
2390        */
2391    }
2392
2393    #[test]
2394    fn query_type() {
2395        crate::init().unwrap();
2396
2397        assert!(!QueryType::Allocation.is_upstream());
2398        assert!(QueryType::Allocation.is_downstream());
2399        assert!(QueryType::Allocation.is_serialized());
2400
2401        assert!(QueryType::Latency.is_upstream());
2402        assert!(QueryType::Latency.is_downstream());
2403        assert!(!QueryType::Latency.is_serialized());
2404
2405        assert!(QueryType::Scheduling.is_upstream());
2406        assert!(!QueryType::Scheduling.is_downstream());
2407        assert!(!QueryType::Scheduling.is_serialized());
2408
2409        let lat = Latency::new();
2410        assert_eq!(lat.type_(), QueryType::Latency);
2411    }
2412}