gstreamer/
stream_collection.rs
1use std::{boxed::Box as Box_, fmt, mem::transmute};
4
5use glib::{
6 object::ObjectType as ObjectType_,
7 signal::{connect_raw, SignalHandlerId},
8 translate::*,
9};
10
11use crate::{ffi, Stream, StreamCollection};
12
13crate::utils::define_fixed_size_iter!(
14 Iter,
15 &'a StreamCollection,
16 Stream,
17 |collection: &StreamCollection| collection.len(),
18 |collection: &StreamCollection, idx: usize| unsafe {
19 from_glib_none(ffi::gst_stream_collection_get_stream(
20 collection.to_glib_none().0,
21 idx as u32,
22 ))
23 }
24);
25
26#[derive(Debug, Clone)]
27#[must_use = "The builder must be built to be used"]
28pub struct StreamCollectionBuilder(StreamCollection);
29
30impl StreamCollectionBuilder {
31 #[doc(alias = "gst_stream_collection_add_stream")]
32 pub fn stream(self, stream: Stream) -> Self {
33 unsafe {
34 ffi::gst_stream_collection_add_stream(
35 (self.0).to_glib_none().0,
36 stream.into_glib_ptr(),
37 );
38 }
39
40 self
41 }
42
43 #[doc(alias = "gst_stream_collection_add_stream")]
44 pub fn stream_if(self, stream: Stream, predicate: bool) -> Self {
45 if predicate {
46 unsafe {
47 ffi::gst_stream_collection_add_stream(
48 (self.0).to_glib_none().0,
49 stream.into_glib_ptr(),
50 );
51 }
52
53 self
54 } else {
55 self
56 }
57 }
58
59 #[doc(alias = "gst_stream_collection_add_stream")]
60 pub fn stream_if_some(self, stream: Option<Stream>) -> Self {
61 if let Some(stream) = stream {
62 self.stream(stream)
63 } else {
64 self
65 }
66 }
67
68 pub fn streams(self, streams: impl IntoIterator<Item = Stream>) -> Self {
69 for stream in streams.into_iter() {
70 unsafe {
71 ffi::gst_stream_collection_add_stream(
72 (self.0).to_glib_none().0,
73 stream.into_glib_ptr(),
74 );
75 }
76 }
77
78 self
79 }
80
81 pub fn streams_if(self, streams: impl IntoIterator<Item = Stream>, predicate: bool) -> Self {
82 if predicate {
83 for stream in streams.into_iter() {
84 unsafe {
85 ffi::gst_stream_collection_add_stream(
86 (self.0).to_glib_none().0,
87 stream.into_glib_ptr(),
88 );
89 }
90 }
91
92 self
93 } else {
94 self
95 }
96 }
97
98 pub fn streams_if_some(self, streams: Option<impl IntoIterator<Item = Stream>>) -> Self {
99 if let Some(streams) = streams {
100 self.streams(streams)
101 } else {
102 self
103 }
104 }
105
106 pub fn streams_if_not_empty(self, streams: impl IntoIterator<Item = Stream>) -> Self {
107 let mut streams = streams.into_iter().peekable();
108 if streams.peek().is_some() {
109 self.streams(streams)
110 } else {
111 self
112 }
113 }
114
115 #[must_use = "Building the stream collection without using it has no effect"]
116 pub fn build(self) -> StreamCollection {
117 self.0
118 }
119}
120
121impl StreamCollection {
122 #[doc(alias = "gst_stream_collection_new")]
123 pub fn builder(upstream_id: Option<&str>) -> StreamCollectionBuilder {
124 assert_initialized_main_thread!();
125 let upstream_id = upstream_id.to_glib_none();
126 let collection = unsafe { from_glib_full(ffi::gst_stream_collection_new(upstream_id.0)) };
127
128 StreamCollectionBuilder(collection)
129 }
130
131 #[doc(alias = "stream-notify")]
138 pub fn connect_stream_notify<
139 F: Fn(&Self, &Stream, &glib::ParamSpec) + Send + Sync + 'static,
140 >(
141 &self,
142 detail: Option<&str>,
143 f: F,
144 ) -> SignalHandlerId {
145 unsafe extern "C" fn stream_notify_trampoline<
146 F: Fn(&StreamCollection, &Stream, &glib::ParamSpec) + Send + Sync + 'static,
147 >(
148 this: *mut ffi::GstStreamCollection,
149 object: *mut ffi::GstStream,
150 p0: *mut glib::gobject_ffi::GParamSpec,
151 f: glib::ffi::gpointer,
152 ) {
153 let f: &F = &*(f as *const F);
154 f(
155 &from_glib_borrow(this),
156 &from_glib_borrow(object),
157 &from_glib_borrow(p0),
158 )
159 }
160 unsafe {
161 let f: Box_<F> = Box_::new(f);
162 let detailed_signal_name = detail.map(|name| format!("stream-notify::{name}\0"));
163 let signal_name: &[u8] = detailed_signal_name
164 .as_ref()
165 .map_or(&b"stream-notify\0"[..], |n| n.as_bytes());
166 connect_raw(
167 self.as_ptr() as *mut _,
168 signal_name.as_ptr() as *const _,
169 Some(transmute::<*const (), unsafe extern "C" fn()>(
170 stream_notify_trampoline::<F> as *const (),
171 )),
172 Box_::into_raw(f),
173 )
174 }
175 }
176
177 pub fn iter(&self) -> Iter {
178 Iter::new(self)
179 }
180
181 pub fn len(&self) -> usize {
182 self.size() as usize
183 }
184
185 pub fn is_empty(&self) -> bool {
186 self.len() == 0
187 }
188
189 pub fn debug(&self) -> Debug {
190 Debug(self)
191 }
192}
193
194impl<'a> IntoIterator for &'a StreamCollection {
195 type IntoIter = Iter<'a>;
196 type Item = Stream;
197
198 fn into_iter(self) -> Self::IntoIter {
199 self.iter()
200 }
201}
202
203pub struct Debug<'a>(&'a StreamCollection);
204
205impl fmt::Debug for Debug<'_> {
206 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
207 struct Streams<'a>(&'a StreamCollection);
208
209 impl fmt::Debug for Streams<'_> {
210 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
211 let mut f = f.debug_list();
212
213 for stream in self.0.iter() {
214 f.entry(&stream.debug());
215 }
216
217 f.finish()
218 }
219 }
220
221 let streams = Streams(self.0);
222
223 f.debug_struct("StreamCollection")
224 .field("streams", &streams)
225 .finish()
226 }
227}