1use glib::translate::*;
4use gst::prelude::*;
5use std::marker::PhantomData;
6
7use crate::{RelTypes, ffi};
8
9#[repr(transparent)]
10#[doc(alias = "GstAnalyticsRelationMeta")]
11pub struct AnalyticsRelationMeta(ffi::GstAnalyticsRelationMeta);
12
13unsafe impl Send for AnalyticsRelationMeta {}
14unsafe impl Sync for AnalyticsRelationMeta {}
15
16#[derive(Debug, Copy, Clone)]
17#[doc(alias = "GstAnalyticsRelationMetaInitParams")]
18pub struct AnalyticsRelationMetaInitParams(ffi::GstAnalyticsRelationMetaInitParams);
19
20impl Default for AnalyticsRelationMetaInitParams {
21 fn default() -> Self {
22 Self(ffi::GstAnalyticsRelationMetaInitParams {
23 initial_relation_order: 0,
24 initial_buf_size: 0,
25 })
26 }
27}
28
29impl AnalyticsRelationMetaInitParams {
30 pub fn new(initial_relation_order: usize, initial_buf_size: usize) -> Self {
31 skip_assert_initialized!();
32 Self(ffi::GstAnalyticsRelationMetaInitParams {
33 initial_relation_order,
34 initial_buf_size,
35 })
36 }
37}
38
39#[derive(Debug, Clone)]
40pub struct AnalyticsMtdRef<'a, T: AnalyticsMtd> {
41 id: u32,
42 meta: gst::MetaRef<'a, AnalyticsRelationMeta>,
43 mtd_type: PhantomData<&'a T>,
44}
45
46#[derive(Debug)]
47pub struct AnalyticsMtdRefMut<'a, T: AnalyticsMtd> {
48 id: u32,
49 meta: &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
50 mtd_type: PhantomData<&'a T>,
51}
52
53pub struct AnalyticsRelationPath {
54 garray: *mut glib::ffi::GArray,
55}
56
57impl std::fmt::Debug for AnalyticsRelationMeta {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
59 f.debug_struct("AnalyticsRelationMeta")
60 .field("len", &self.len())
61 .finish()
62 }
63}
64
65impl AnalyticsRelationMeta {
66 #[doc(alias = "gst_buffer_add_analytics_relation_meta")]
67 pub fn add(buffer: &mut gst::BufferRef) -> gst::MetaRefMut<'_, Self, gst::meta::Standalone> {
68 skip_assert_initialized!();
69
70 unsafe {
71 let meta_ptr = ffi::gst_buffer_add_analytics_relation_meta(buffer.as_mut_ptr());
72 Self::from_mut_ptr(buffer, meta_ptr)
73 }
74 }
75
76 #[doc(alias = "gst_buffer_add_analytics_relation_meta_full")]
77 pub fn add_full<'a>(
78 buffer: &'a mut gst::BufferRef,
79 init_params: &AnalyticsRelationMetaInitParams,
80 ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
81 skip_assert_initialized!();
82
83 unsafe {
84 let meta_ptr = ffi::gst_buffer_add_analytics_relation_meta_full(
85 buffer.as_mut_ptr(),
86 mut_override(&init_params.0),
87 );
88 Self::from_mut_ptr(buffer, meta_ptr)
89 }
90 }
91
92 #[doc(alias = "gst_analytics_relation_get_length")]
93 pub fn len(&self) -> usize {
94 unsafe { ffi::gst_analytics_relation_get_length(self.as_mut_ptr()) }
95 }
96
97 pub fn is_empty(&self) -> bool {
98 self.len() == 0
99 }
100
101 #[doc(alias = "gst_analytics_relation_meta_set_relation")]
102 pub fn set_relation(
103 &mut self,
104 type_: crate::RelTypes,
105 an_meta_first_id: u32,
106 an_meta_second_id: u32,
107 ) -> Result<(), glib::BoolError> {
108 let ret = unsafe {
109 from_glib(ffi::gst_analytics_relation_meta_set_relation(
110 self.as_mut_ptr(),
111 type_.into_glib(),
112 an_meta_first_id,
113 an_meta_second_id,
114 ))
115 };
116
117 if ret {
118 Ok(())
119 } else {
120 Err(glib::bool_error!(
121 "Could not set relation {:}->{:} of type {:?}",
122 an_meta_first_id,
123 an_meta_second_id,
124 type_
125 ))
126 }
127 }
128
129 #[doc(alias = "gst_analytics_relation_meta_get_relation")]
130 pub fn relation(&self, an_meta_first_id: u32, an_meta_second_id: u32) -> crate::RelTypes {
131 unsafe {
132 from_glib(ffi::gst_analytics_relation_meta_get_relation(
133 self.as_mut_ptr(),
134 an_meta_first_id,
135 an_meta_second_id,
136 ))
137 }
138 }
139
140 #[doc(alias = "gst_analytics_relation_meta_exist")]
141 pub fn exist(
142 &self,
143 an_meta_first_id: u32,
144 an_meta_second_id: u32,
145 relation_span: i32,
146 cond_types: crate::RelTypes,
147 ) -> bool {
148 unsafe {
149 from_glib(ffi::gst_analytics_relation_meta_exist(
150 self.as_mut_ptr(),
151 an_meta_first_id,
152 an_meta_second_id,
153 relation_span,
154 cond_types.into_glib(),
155 std::ptr::null_mut(),
156 ))
157 }
158 }
159
160 #[doc(alias = "gst_analytics_relation_meta_exist")]
161 pub fn exist_path(
162 &self,
163 an_meta_first_id: u32,
164 an_meta_second_id: u32,
165 relation_span: i32,
166 cond_types: crate::RelTypes,
167 ) -> Result<AnalyticsRelationPath, glib::BoolError> {
168 let mut array = std::ptr::null_mut::<glib::ffi::GArray>();
169 let ret = unsafe {
170 from_glib(ffi::gst_analytics_relation_meta_exist(
171 self.as_mut_ptr(),
172 an_meta_first_id,
173 an_meta_second_id,
174 relation_span,
175 cond_types.into_glib(),
176 &mut array,
177 ))
178 };
179
180 if ret {
181 Ok(AnalyticsRelationPath { garray: array })
182 } else {
183 Err(glib::bool_error!("Such relation doesn't exist"))
184 }
185 }
186
187 pub unsafe fn as_mut_ptr(&self) -> *mut ffi::GstAnalyticsRelationMeta {
188 mut_override(&self.0)
189 }
190}
191
192impl UnsafeFrom<&AnalyticsRelationMeta> for ffi::GstAnalyticsMtd {
193 unsafe fn unsafe_from(t: &AnalyticsRelationMeta) -> Self {
194 unsafe {
195 ffi::GstAnalyticsMtd {
196 id: 0,
197 meta: t.as_mut_ptr(),
198 }
199 }
200 }
201}
202
203impl AnalyticsRelationPath {
204 pub fn as_slice(&self) -> &[u32] {
205 unsafe {
206 std::slice::from_raw_parts(
207 (*self.garray).data as *const u32,
208 (*self.garray).len as usize,
209 )
210 }
211 }
212}
213
214impl Drop for AnalyticsRelationPath {
215 fn drop(&mut self) {
216 unsafe {
217 glib::ffi::g_array_free(self.garray, glib::ffi::GTRUE);
218 }
219 }
220}
221
222mod sealed {
223 pub trait Sealed {}
224 impl<T> Sealed for T {}
225}
226
227pub trait AnalyticsMetaRefExt<'a>: sealed::Sealed {
228 #[doc(alias = "gst_analytics_relation_meta_get_mtd")]
229 fn mtd<T: AnalyticsMtd>(&self, an_meta_id: u32) -> Option<AnalyticsMtdRef<'a, T>>;
230 fn iter<T: AnalyticsMtd>(&'a self) -> AnalyticsMtdIter<'a, T>;
231 fn iter_direct_related<T: AnalyticsMtd>(
232 &'a self,
233 an_meta_id: u32,
234 rel_type: RelTypes,
235 ) -> AnalyticsMtdIter<'a, T>;
236}
237
238impl<'a> AnalyticsMetaRefExt<'a> for gst::MetaRef<'a, AnalyticsRelationMeta> {
239 fn mtd<T: AnalyticsMtd>(&self, an_meta_id: u32) -> Option<AnalyticsMtdRef<'a, T>> {
240 unsafe {
241 let mut mtd = std::mem::MaybeUninit::uninit();
242 let ret = from_glib(ffi::gst_analytics_relation_meta_get_mtd(
243 self.as_mut_ptr(),
244 an_meta_id,
245 T::mtd_type(),
246 mtd.as_mut_ptr(),
247 ));
248 let id = mtd.assume_init().id;
249
250 if ret {
251 Some(AnalyticsMtdRef::from_meta(self, id))
252 } else {
253 None
254 }
255 }
256 }
257
258 fn iter<T: AnalyticsMtd>(&'a self) -> AnalyticsMtdIter<'a, T> {
259 AnalyticsMtdIter::new(self)
260 }
261 fn iter_direct_related<T: AnalyticsMtd>(
262 &'a self,
263 an_meta_id: u32,
264 rel_type: RelTypes,
265 ) -> AnalyticsMtdIter<'a, T> {
266 AnalyticsMtdIter::new_direct_related(self, an_meta_id, rel_type.into_glib())
267 }
268}
269
270impl<'a, T: AnalyticsMtd> AnalyticsMtdRef<'a, T> {
271 pub fn id(&self) -> u32 {
272 self.id
273 }
274
275 #[cfg(feature = "v1_28")]
276 pub(crate) fn meta_ref(&self) -> &gst::MetaRef<'a, AnalyticsRelationMeta> {
277 &self.meta
278 }
279
280 pub unsafe fn from_meta(meta: &gst::MetaRef<'a, AnalyticsRelationMeta>, id: u32) -> Self {
281 skip_assert_initialized!();
282 AnalyticsMtdRef {
283 meta: meta.clone(),
284 id,
285 mtd_type: PhantomData,
286 }
287 }
288
289 #[doc(alias = "gst_analytics_mtd_get_mtd_type")]
290 pub fn mtd_type(&self) -> ffi::GstAnalyticsMtdType {
291 unsafe {
292 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
293 ffi::gst_analytics_mtd_get_mtd_type(&mtd)
294 }
295 }
296
297 #[cfg(feature = "v1_30")]
298 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
299 #[doc(alias = "gst_analytics_mtd_get_semantic_tag")]
300 pub fn semantic_tag(&self) -> Result<glib::GString, glib::BoolError> {
301 unsafe {
302 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
303 let tag = ffi::gst_analytics_mtd_get_semantic_tag(&mtd);
304 if tag.is_null() {
305 Err(glib::bool_error!("Could not retrieve semantic tag"))
306 } else {
307 Ok(from_glib_full(tag))
308 }
309 }
310 }
311
312 #[cfg(feature = "v1_30")]
313 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
314 #[doc(alias = "gst_analytics_mtd_has_semantic_tag")]
315 pub fn has_semantic_tag(&self, tag: &str) -> bool {
316 unsafe {
317 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
318 from_glib(ffi::gst_analytics_mtd_has_semantic_tag(
319 &mtd,
320 tag.to_glib_none().0,
321 ))
322 }
323 }
324
325 #[cfg(feature = "v1_30")]
326 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
327 #[doc(alias = "gst_analytics_mtd_semantic_tag_has_prefix")]
328 pub fn semantic_tag_has_prefix(&self, prefix: &str) -> bool {
329 unsafe {
330 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
331 from_glib(ffi::gst_analytics_mtd_semantic_tag_has_prefix(
332 &mtd,
333 prefix.to_glib_none().0,
334 ))
335 }
336 }
337}
338impl<'a> AnalyticsMtdRef<'a, AnalyticsAnyMtd> {
339 pub fn downcast<T: AnalyticsMtd>(
340 self,
341 ) -> Result<AnalyticsMtdRef<'a, T>, AnalyticsMtdRef<'a, AnalyticsAnyMtd>> {
342 if self.mtd_type() == T::mtd_type() {
343 Ok(AnalyticsMtdRef {
344 id: self.id,
345 meta: self.meta,
346 mtd_type: PhantomData,
347 })
348 } else {
349 Err(self)
350 }
351 }
352
353 pub fn downcast_ref<T: AnalyticsMtd>(&self) -> Option<&AnalyticsMtdRef<'a, T>> {
354 unsafe {
355 if self.mtd_type() == T::mtd_type() {
356 Some(&*(self as *const _ as *const _))
357 } else {
358 None
359 }
360 }
361 }
362}
363
364impl<'a> AnalyticsMtdRefMut<'a, AnalyticsAnyMtd> {
365 pub fn downcast_mut<T: AnalyticsMtd>(&mut self) -> Option<&mut AnalyticsMtdRefMut<'a, T>> {
366 unsafe {
367 if self.as_ref().mtd_type() == T::mtd_type() {
368 Some(&mut *(self as *mut _ as *mut _))
369 } else {
370 None
371 }
372 }
373 }
374}
375
376impl<'a, T: AnalyticsMtd> UnsafeFrom<&AnalyticsMtdRef<'a, T>> for ffi::GstAnalyticsMtd {
377 unsafe fn unsafe_from(t: &AnalyticsMtdRef<'a, T>) -> Self {
378 unsafe {
379 ffi::GstAnalyticsMtd {
380 id: t.id,
381 meta: t.meta.as_mut_ptr(),
382 }
383 }
384 }
385}
386
387pub trait AnalyticsMetaRefMutExt<'a>: sealed::Sealed {
388 #[doc(alias = "gst_analytics_relation_meta_get_mtd")]
389 fn mtd_mut<T: AnalyticsMtd>(&'a mut self, an_meta_id: u32)
390 -> Option<AnalyticsMtdRefMut<'a, T>>;
391
392 fn iter_mut<T: AnalyticsMtd>(&'a mut self) -> AnalyticsMtdIterMut<'a, T>;
393 fn iter_direct_related_mut<T: AnalyticsMtd>(
394 &'a mut self,
395 an_meta_id: u32,
396 rel_type: RelTypes,
397 ) -> AnalyticsMtdIterMut<'a, T>;
398}
399
400impl<'a> AnalyticsMetaRefMutExt<'a>
401 for gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>
402{
403 fn mtd_mut<T: AnalyticsMtd>(
404 &'a mut self,
405 an_meta_id: u32,
406 ) -> Option<AnalyticsMtdRefMut<'a, T>> {
407 unsafe {
408 let mut mtd = std::mem::MaybeUninit::uninit();
409 let ret = from_glib(ffi::gst_analytics_relation_meta_get_mtd(
410 self.as_mut_ptr(),
411 an_meta_id,
412 T::mtd_type(),
413 mtd.as_mut_ptr(),
414 ));
415 let id = mtd.assume_init().id;
416
417 if ret {
418 Some(AnalyticsMtdRefMut::from_meta(self, id))
419 } else {
420 None
421 }
422 }
423 }
424
425 fn iter_mut<T: AnalyticsMtd>(&'a mut self) -> AnalyticsMtdIterMut<'a, T> {
426 AnalyticsMtdIterMut::new(self)
427 }
428 fn iter_direct_related_mut<T: AnalyticsMtd>(
429 &'a mut self,
430 an_meta_id: u32,
431 rel_type: RelTypes,
432 ) -> AnalyticsMtdIterMut<'a, T> {
433 AnalyticsMtdIterMut::new_direct_related(self, an_meta_id, rel_type.into_glib())
434 }
435}
436
437unsafe impl MetaAPI for AnalyticsRelationMeta {
438 type GstType = ffi::GstAnalyticsRelationMeta;
439
440 #[doc(alias = "gst_analytics_relation_meta_api_get_type")]
441 #[inline]
442 fn meta_api() -> glib::Type {
443 unsafe { from_glib(ffi::gst_analytics_relation_meta_api_get_type()) }
444 }
445}
446
447pub unsafe trait AnalyticsMtd {
448 fn mtd_type() -> ffi::GstAnalyticsMtdType;
449}
450
451pub trait AnalyticsMtdExt: AnalyticsMtd {
452 #[doc(alias = "gst_analytics_mtd_type_get_name")]
453 fn type_name() -> &'static str {
454 unsafe {
455 let ptr = ffi::gst_analytics_mtd_type_get_name(Self::mtd_type());
456 std::ffi::CStr::from_ptr(ptr).to_str().unwrap()
457 }
458 }
459}
460
461impl<T: AnalyticsMtd> AnalyticsMtdExt for T {}
462
463impl<'a, T: AnalyticsMtd> AnalyticsMtdRefMut<'a, T> {
464 pub fn id(&self) -> u32 {
465 self.id
466 }
467
468 pub unsafe fn from_meta(
469 meta: &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
470 id: u32,
471 ) -> Self {
472 skip_assert_initialized!();
473 AnalyticsMtdRefMut {
474 meta,
475 id,
476 mtd_type: PhantomData,
477 }
478 }
479
480 #[cfg(feature = "v1_30")]
481 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
482 #[doc(alias = "gst_analytics_mtd_set_semantic_tag")]
483 pub fn set_semantic_tag(&mut self, tag: &str) -> Result<(), glib::BoolError> {
484 let ret = unsafe {
485 let mut mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
486 from_glib(ffi::gst_analytics_mtd_set_semantic_tag(
487 &mut mtd,
488 tag.to_glib_none().0,
489 ))
490 };
491
492 if ret {
493 Ok(())
494 } else {
495 Err(glib::bool_error!("Couldn't set semantic tag"))
496 }
497 }
498}
499
500impl<'a, T: AnalyticsMtd> UnsafeFrom<&mut AnalyticsMtdRefMut<'a, T>> for ffi::GstAnalyticsMtd {
501 unsafe fn unsafe_from(t: &mut AnalyticsMtdRefMut<'a, T>) -> Self {
502 ffi::GstAnalyticsMtd {
503 id: t.id,
504 meta: t.meta.as_mut_ptr(),
505 }
506 }
507}
508
509impl<'a, T: AnalyticsMtd> From<AnalyticsMtdRefMut<'a, T>> for AnalyticsMtdRef<'a, T> {
510 fn from(value: AnalyticsMtdRefMut<'a, T>) -> Self {
511 skip_assert_initialized!();
512 AnalyticsMtdRef {
513 meta: value.meta.as_ref().clone(),
514 id: value.id,
515 mtd_type: value.mtd_type,
516 }
517 }
518}
519
520impl<'a, T: AnalyticsMtd> From<&mut AnalyticsMtdRefMut<'a, T>> for AnalyticsMtdRef<'a, T> {
521 fn from(value: &mut AnalyticsMtdRefMut<'a, T>) -> Self {
522 skip_assert_initialized!();
523 AnalyticsMtdRef {
524 meta: value.meta.as_ref().clone(),
525 id: value.id,
526 mtd_type: value.mtd_type,
527 }
528 }
529}
530
531impl<'a, T: AnalyticsMtd> AsRef<AnalyticsMtdRef<'a, T>> for AnalyticsMtdRefMut<'a, T> {
532 #[inline]
533 fn as_ref(&self) -> &AnalyticsMtdRef<'a, T> {
534 unsafe { &*(self as *const AnalyticsMtdRefMut<'a, T> as *const AnalyticsMtdRef<'a, T>) }
535 }
536}
537
538macro_rules! define_mtd_iter {
539 ($name:ident, $metaref:ty, $itemref:ty, $copy_meta:expr) => {
540 #[must_use = "iterators are lazy and do nothing unless consumed"]
541 pub struct $name<'a, T: AnalyticsMtd> {
542 meta: $metaref,
543 state: glib::ffi::gpointer,
544 mtd_type: ffi::GstAnalyticsMtdType,
545 an_meta_id: u32,
546 rel_type: ffi::GstAnalyticsRelTypes,
547 phantom: std::marker::PhantomData<T>,
548 }
549
550 impl<'a, T: AnalyticsMtd> $name<'a, T> {
551 fn new(meta: $metaref) -> Self {
552 skip_assert_initialized!();
553 $name {
554 meta,
555 state: std::ptr::null_mut(),
556 mtd_type: T::mtd_type(),
557 an_meta_id: u32::MAX,
558 rel_type: RelTypes::ANY.into_glib(),
559 phantom: PhantomData,
560 }
561 }
562 fn new_direct_related(
563 meta: $metaref,
564 an_meta_id: u32,
565 rel_type: ffi::GstAnalyticsRelTypes,
566 ) -> Self {
567 skip_assert_initialized!();
568 $name {
569 meta,
570 state: std::ptr::null_mut(),
571 mtd_type: T::mtd_type(),
572 an_meta_id,
573 rel_type,
574 phantom: PhantomData,
575 }
576 }
577 }
578
579 impl<'a, T: AnalyticsMtd + 'a> Iterator for $name<'a, T> {
580 type Item = $itemref;
581
582 fn next(&mut self) -> Option<Self::Item> {
583 unsafe {
584 let mut mtd = ffi::GstAnalyticsMtd::unsafe_from(&**self.meta);
585 let ret = {
586 if self.an_meta_id == u32::MAX {
587 ffi::gst_analytics_relation_meta_iterate(
588 self.meta.as_mut_ptr(),
589 &mut self.state,
590 self.mtd_type,
591 &mut mtd,
592 )
593 } else {
594 ffi::gst_analytics_relation_meta_get_direct_related(
595 self.meta.as_mut_ptr(),
596 self.an_meta_id,
597 self.rel_type,
598 self.mtd_type,
599 &mut self.state,
600 &mut mtd,
601 )
602 }
603 };
604 if from_glib(ret) {
605 #[allow(clippy::redundant_closure_call)]
608 Some(Self::Item::from_meta($copy_meta(self.meta), mtd.id))
609 } else {
610 None
611 }
612 }
613 }
614 }
615 };
616}
617
618define_mtd_iter!(
619 AnalyticsMtdIter,
620 &'a gst::MetaRef<'a, AnalyticsRelationMeta>,
621 AnalyticsMtdRef<'a, T>,
622 |meta| meta
623);
624
625define_mtd_iter!(
626 AnalyticsMtdIterMut,
627 &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
628 AnalyticsMtdRefMut<'a, T>,
629 |meta: &mut _| &mut *(meta as *mut gst::MetaRefMut<
630 'a,
631 AnalyticsRelationMeta,
632 gst::meta::Standalone,
633 >)
634);
635
636#[derive(Debug)]
637pub enum AnalyticsAnyMtd {}
638
639unsafe impl AnalyticsMtd for AnalyticsAnyMtd {
640 fn mtd_type() -> ffi::GstAnalyticsMtdType {
641 ffi::GST_ANALYTICS_MTD_TYPE_ANY as ffi::GstAnalyticsMtdType
642 }
643}
644
645#[cfg(test)]
646mod tests {
647 use crate::*;
648
649 #[test]
650 fn build_relation_meta() {
651 gst::init().unwrap();
652
653 let mut buf = gst::Buffer::new();
654
655 let meta = AnalyticsRelationMeta::add(buf.make_mut());
656
657 assert!(meta.is_empty());
658 }
659
660 #[test]
661 fn build_relation_meta_full() {
662 gst::init().unwrap();
663
664 let mut buf = gst::Buffer::new();
665
666 let params = AnalyticsRelationMetaInitParams::new(10, 10);
667 let meta = AnalyticsRelationMeta::add_full(buf.make_mut(), ¶ms);
668
669 assert!(meta.is_empty());
670 }
671
672 #[test]
673 fn relations() {
674 gst::init().unwrap();
675
676 let mut buf = gst::Buffer::new();
677 let _ = AnalyticsRelationMeta::add(buf.make_mut());
678
679 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
680 let od = meta
681 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
682 .unwrap();
683 let od1_id = od.id();
684
685 let od = meta
686 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
687 .unwrap();
688 let od2_id = od.id();
689
690 let od: AnalyticsMtdRef<'_, AnalyticsODMtd> = meta
691 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
692 .unwrap();
693 let od3_id = od.id();
694
695 meta.set_relation(RelTypes::IS_PART_OF, od1_id, od2_id)
696 .unwrap();
697 meta.set_relation(RelTypes::IS_PART_OF, od2_id, od3_id)
698 .unwrap();
699
700 meta.set_relation(RelTypes::IS_PART_OF, 8888, 9999)
701 .expect_err("Invalid id");
702
703 let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
704 assert!(meta.relation(od1_id, od2_id) == crate::RelTypes::IS_PART_OF);
705 assert!(meta.relation(od2_id, od3_id) == crate::RelTypes::IS_PART_OF);
706
707 assert!(meta.exist(od1_id, od2_id, 1, crate::RelTypes::IS_PART_OF));
708 assert!(meta.exist(od1_id, od3_id, 2, crate::RelTypes::IS_PART_OF));
709 assert!(!meta.exist(od2_id, od1_id, 1, crate::RelTypes::IS_PART_OF));
710 assert!(!meta.exist(od1_id, od3_id, 1, crate::RelTypes::IS_PART_OF));
711 assert!(!meta.exist(od1_id, od2_id, 1, crate::RelTypes::CONTAIN));
712
713 let path = meta
714 .exist_path(od1_id, od3_id, 3, crate::RelTypes::ANY)
715 .unwrap();
716
717 assert_eq!(path.as_slice().len(), 3);
718 assert_eq!(path.as_slice()[0], od1_id);
719 assert_eq!(path.as_slice()[1], od2_id);
720 assert_eq!(path.as_slice()[2], od3_id);
721
722 assert_eq!(meta.len(), meta.iter::<AnalyticsAnyMtd>().count());
723 assert_eq!(meta.len(), meta.iter::<AnalyticsODMtd>().count());
724 for mtd in meta.iter::<AnalyticsODMtd>() {
725 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
726 }
727
728 assert_eq!(meta.len(), meta.iter::<AnalyticsAnyMtd>().count());
729 for mtd in meta.iter::<AnalyticsAnyMtd>() {
730 if let Ok(mtd) = mtd.downcast::<AnalyticsODMtd>() {
731 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
732 }
733 }
734
735 assert_eq!(
736 meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::IS_PART_OF)
737 .count(),
738 1
739 );
740 assert_eq!(
741 meta.iter_direct_related::<AnalyticsODMtd>(od2_id, crate::RelTypes::IS_PART_OF)
742 .count(),
743 1
744 );
745 assert_eq!(
746 meta.iter_direct_related::<AnalyticsODMtd>(od3_id, crate::RelTypes::IS_PART_OF)
747 .count(),
748 0
749 );
750 assert_eq!(
751 meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::CONTAIN)
752 .count(),
753 0
754 );
755
756 assert_eq!(
757 meta.iter_direct_related::<AnalyticsAnyMtd>(od1_id, crate::RelTypes::CONTAIN)
758 .count(),
759 0
760 );
761 for mtd in meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::IS_PART_OF) {
762 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
763 }
764
765 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
766 assert_eq!(meta.len(), meta.iter_mut::<AnalyticsAnyMtd>().count());
767
768 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
769 let _ = meta.add_tracking_mtd(10, gst::ClockTime::from_seconds(10));
770 let _ = meta.add_tracking_mtd(10, gst::ClockTime::from_seconds(10));
771
772 for mut item in meta.iter_mut::<AnalyticsTrackingMtd>() {
773 item.set_lost().unwrap();
774 }
775 }
776}