Skip to main content

gstreamer/
flag_serde.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::{
4    FlagsClass,
5    prelude::*,
6    translate::{ToGlibPtr, from_glib},
7};
8
9bitflags_serde_impl!(crate::BinFlags);
10bitflags_serde_impl!(crate::BufferCopyFlags);
11bitflags_serde_impl!(crate::BufferFlags);
12bitflags_serde_impl!(crate::BufferPoolAcquireFlags);
13bitflags_serde_impl!(crate::ClockFlags);
14
15impl serde::Serialize for crate::DebugColorFlags {
16    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
17    where
18        S: serde::Serializer,
19    {
20        serializer.serialize_str(&format!(
21            "{}+{}{}{}",
22            match *self & Self::from_bits(0b111).expect("Failed to create value from fg-color mask")
23            {
24                Self::FG_BLACK => "fg-black",
25                Self::FG_RED => "fg-red",
26                Self::FG_GREEN => "fg-green",
27                Self::FG_YELLOW => "fg-yellow",
28                Self::FG_BLUE => "fg-blue",
29                Self::FG_MAGENTA => "fg-magenta",
30                Self::FG_CYAN => "fg-cyan",
31                Self::FG_WHITE => "fg-white",
32                _ => unreachable!(),
33            },
34            match *self
35                & Self::from_bits(0b111_0000).expect("Failed to create value from bg-color mask")
36            {
37                Self::BG_BLACK => "bg-black",
38                Self::BG_RED => "bg-red",
39                Self::BG_GREEN => "bg-green",
40                Self::BG_YELLOW => "bg-yellow",
41                Self::BG_BLUE => "bg-blue",
42                Self::BG_MAGENTA => "bg-magenta",
43                Self::BG_CYAN => "bg-cyan",
44                Self::BG_WHITE => "bg-white",
45                _ => unreachable!(),
46            },
47            if self.contains(Self::BOLD) {
48                "+bold"
49            } else {
50                ""
51            },
52            if self.contains(Self::UNDERLINE) {
53                "+underline"
54            } else {
55                ""
56            }
57        ))
58    }
59}
60
61bitflags_deserialize_impl!(crate::DebugColorFlags);
62bitflags_serialize_impl!(crate::DebugGraphDetails, by_ones_decreasing);
63bitflags_deserialize_impl!(crate::DebugGraphDetails);
64bitflags_serde_impl!(crate::ElementFlags);
65bitflags_serde_impl!(crate::EventTypeFlags);
66bitflags_serde_impl!(crate::GapFlags, "v1_20");
67bitflags_serde_impl!(crate::MemoryFlags);
68bitflags_serde_impl!(crate::MetaFlags);
69bitflags_serde_impl!(crate::ObjectFlags);
70bitflags_serde_impl!(crate::PadFlags);
71bitflags_serde_impl!(crate::PadLinkCheck);
72bitflags_serde_impl!(crate::PadProbeType);
73bitflags_serde_impl!(crate::ParseFlags);
74bitflags_serde_impl!(crate::PluginAPIFlags, "v1_18");
75bitflags_serde_impl!(crate::PluginDependencyFlags);
76bitflags_serde_impl!(crate::PluginFlags);
77bitflags_serde_impl!(crate::SchedulingFlags);
78bitflags_serde_impl!(crate::SeekFlags);
79bitflags_serde_impl!(crate::SegmentFlags);
80bitflags_serde_impl!(crate::SerializeFlags, "v1_20");
81bitflags_serde_impl!(crate::StackTraceFlags);
82bitflags_serde_impl!(crate::StreamFlags);
83bitflags_serde_impl!(crate::StreamType);
84
85#[cfg(test)]
86mod tests {
87    macro_rules! check_serialize {
88        ($flags:expr, $expected:expr) => {
89            let actual = serde_json::to_string(&$flags).unwrap();
90            assert_eq!(actual, $expected);
91        };
92    }
93
94    macro_rules! check_deserialize {
95        ($ty:ty, $expected:expr, $json:expr) => {
96            let actual: $ty = serde_json::from_str(&$json).unwrap();
97            assert_eq!(actual, $expected);
98        };
99    }
100
101    macro_rules! check_roundtrip {
102        ($ty:ty, $flags:expr) => {
103            let json = serde_json::to_string(&$flags).unwrap();
104            let deserialized: $ty = serde_json::from_str(&json).unwrap();
105            assert_eq!(deserialized, $flags);
106        };
107    }
108
109    #[test]
110    fn test_serialize() {
111        crate::init().unwrap();
112
113        check_serialize!(crate::BinFlags::empty(), "\"\"");
114        check_serialize!(crate::BinFlags::all(), "\"no-resync+streams-aware\"");
115        check_serialize!(
116            crate::BufferCopyFlags::all(),
117            "\"flags+timestamps+meta+memory+merge+deep\""
118        );
119        check_serialize!(
120            crate::BufferFlags::all(),
121            concat!(
122                "\"live+decode-only+discont+resync+corrupted+marker+header+gap",
123                "+droppable+delta-unit+tag-memory+sync-after+non-droppable\""
124            )
125        );
126        check_serialize!(
127            crate::BufferPoolAcquireFlags::all(),
128            "\"key-unit+dontwait+discont\""
129        );
130        check_serialize!(
131            crate::ClockFlags::all(),
132            concat!(
133                "\"can-do-single-sync+can-do-single-async",
134                "+can-do-periodic-sync+can-do-periodic-async",
135                "+can-set-resolution+can-set-master+needs-startup-sync\""
136            )
137        );
138
139        check_serialize!(
140            crate::DebugColorFlags::all(),
141            "\"fg-white+bg-white+bold+underline\""
142        );
143        check_serialize!(
144            crate::DebugColorFlags::FG_MAGENTA | crate::DebugColorFlags::BOLD,
145            "\"fg-magenta+bg-black+bold\""
146        );
147        check_serialize!(
148            crate::DebugColorFlags::FG_RED
149                | crate::DebugColorFlags::FG_BLUE
150                | crate::DebugColorFlags::BG_BLACK,
151            "\"fg-magenta+bg-black\""
152        );
153
154        check_serialize!(crate::DebugGraphDetails::all(), "\"verbose\"");
155        check_serialize!(
156            crate::DebugGraphDetails::MEDIA_TYPE
157                | crate::DebugGraphDetails::CAPS_DETAILS
158                | crate::DebugGraphDetails::NON_DEFAULT_PARAMS
159                | crate::DebugGraphDetails::STATES
160                | crate::DebugGraphDetails::FULL_PARAMS
161                | crate::DebugGraphDetails::ALL,
162            "\"all+full-params\""
163        );
164        check_serialize!(
165            crate::DebugGraphDetails::MEDIA_TYPE
166                | crate::DebugGraphDetails::CAPS_DETAILS
167                | crate::DebugGraphDetails::NON_DEFAULT_PARAMS
168                | crate::DebugGraphDetails::STATES
169                | crate::DebugGraphDetails::FULL_PARAMS,
170            "\"all+full-params\""
171        );
172
173        check_serialize!(
174            crate::ElementFlags::all(),
175            "\"locked-state+sink+source+provide-clock+require-clock+indexable\""
176        );
177        check_serialize!(
178            crate::EventTypeFlags::all(),
179            "\"upstream+downstream+serialized+sticky+sticky-multi\""
180        );
181        #[cfg(feature = "v1_20")]
182        check_serialize!(crate::GapFlags::all(), "\"data\"");
183        check_serialize!(
184            crate::MemoryFlags::all(),
185            concat!(
186                "\"readonly+no-share+zero-prefixed+zero-padded",
187                "+physically-contiguous+not-mappable\""
188            )
189        );
190        check_serialize!(crate::MetaFlags::all(), "\"readonly+pooled+locked\"");
191        cfg_if::cfg_if! {
192            if #[cfg(feature = "v1_24")] {
193                check_serialize!(crate::ObjectFlags::all(), "\"may-be-leaked+constructed\"");
194            } else {
195                check_serialize!(crate::ObjectFlags::all(), "\"may-be-leaked\"");
196            }
197        }
198        check_serialize!(
199            crate::PadFlags::all(),
200            concat!(
201                "\"blocked+flushing+eos+blocking+need-parent+need-reconfigure",
202                "+pending-events+fixed-caps+proxy-caps+proxy-allocation",
203                "+proxy-scheduling+accept-intersect+accept-template\""
204            )
205        );
206        check_serialize!(
207            crate::PadLinkCheck::all(),
208            "\"hierarchy+template-caps+caps+no-reconfigure\""
209        );
210        check_serialize!(
211            crate::PadProbeType::all(),
212            concat!(
213                "\"idle+block+buffer+buffer-list+event-downstream",
214                "+event-upstream+event-flush+query-downstream+query-upstream",
215                "+push+pull\""
216            )
217        );
218        check_serialize!(
219            crate::ParseFlags::all(),
220            "\"fatal-errors+no-single-element-bins+place-in-bin\""
221        );
222        #[cfg(feature = "v1_18")]
223        check_serialize!(crate::PluginAPIFlags::all(), "\"members\"");
224        check_serialize!(
225            crate::PluginDependencyFlags::all(),
226            concat!(
227                "\"recurse+paths-are-default-only+file-name-is-suffix",
228                "+file-name-is-prefix+paths-are-relative-to-exe\""
229            )
230        );
231        cfg_if::cfg_if! {
232            if #[cfg(feature = "v1_30")] {
233                check_serialize!(crate::PluginFlags::all(), "\"cached+blacklisted+static-features\"");
234            } else {
235                check_serialize!(crate::PluginFlags::all(), "\"cached+blacklisted\"");
236            }
237        }
238        check_serialize!(
239            crate::SchedulingFlags::all(),
240            "\"seekable+sequential+bandwidth-limited\""
241        );
242        #[cfg(feature = "v1_18")]
243        check_serialize!(
244            crate::SeekFlags::all(),
245            concat!(
246                "\"flush+accurate+key-unit+segment+trickmode+snap-before",
247                "+snap-after+trickmode-key-units+trickmode-no-audio",
248                "+trickmode-forward-predicted+instant-rate-change\""
249            )
250        );
251        #[cfg(feature = "v1_18")]
252        check_serialize!(
253            crate::SegmentFlags::all(),
254            concat!(
255                "\"reset+trickmode+segment+trickmode-key-units",
256                "+trickmode-forward-predicted+trickmode-no-audio\""
257            )
258        );
259        #[cfg(feature = "v1_20")]
260        check_serialize!(crate::SerializeFlags::all(), "\"backward-compat\"");
261        check_serialize!(crate::StackTraceFlags::all(), "\"full\"");
262        check_serialize!(crate::StreamFlags::all(), "\"sparse+select+unselect\"");
263        check_serialize!(
264            crate::StreamType::all(),
265            "\"unknown+audio+video+container+text+metadata\""
266        );
267    }
268
269    #[test]
270    fn test_deserialize() {
271        crate::init().unwrap();
272
273        check_deserialize!(crate::BinFlags, crate::BinFlags::empty(), "\"\"");
274        check_deserialize!(
275            crate::BinFlags,
276            crate::BinFlags::all(),
277            "\"no-resync+streams-aware\""
278        );
279        check_deserialize!(
280            crate::BufferCopyFlags,
281            crate::BufferCopyFlags::all(),
282            "\"flags+timestamps+meta+memory+merge+deep\""
283        );
284        check_deserialize!(
285            crate::BufferFlags,
286            crate::BufferFlags::all(),
287            concat!(
288                "\"live+decode-only+discont+resync+corrupted+marker+header+gap",
289                "+droppable+delta-unit+tag-memory+sync-after+non-droppable\""
290            )
291        );
292        check_deserialize!(
293            crate::BufferPoolAcquireFlags,
294            crate::BufferPoolAcquireFlags::all(),
295            "\"key-unit+dontwait+discont\""
296        );
297        check_deserialize!(
298            crate::ClockFlags,
299            crate::ClockFlags::all(),
300            concat!(
301                "\"can-do-single-sync+can-do-single-async",
302                "+can-do-periodic-sync+can-do-periodic-async",
303                "+can-set-resolution+can-set-master+needs-startup-sync\""
304            )
305        );
306
307        check_deserialize!(
308            crate::DebugColorFlags,
309            crate::DebugColorFlags::all(),
310            "\"fg-white+bg-white+bold+underline\""
311        );
312        check_deserialize!(
313            crate::DebugColorFlags,
314            crate::DebugColorFlags::FG_MAGENTA | crate::DebugColorFlags::BOLD,
315            "\"fg-magenta+bg-black+bold\""
316        );
317        check_deserialize!(
318            crate::DebugColorFlags,
319            crate::DebugColorFlags::FG_RED
320                | crate::DebugColorFlags::FG_BLUE
321                | crate::DebugColorFlags::BG_BLACK,
322            "\"fg-magenta+bg-black\""
323        );
324
325        check_deserialize!(
326            crate::DebugGraphDetails,
327            crate::DebugGraphDetails::all(),
328            "\"verbose\""
329        );
330        check_deserialize!(
331            crate::DebugGraphDetails,
332            crate::DebugGraphDetails::MEDIA_TYPE
333                | crate::DebugGraphDetails::CAPS_DETAILS
334                | crate::DebugGraphDetails::NON_DEFAULT_PARAMS
335                | crate::DebugGraphDetails::STATES
336                | crate::DebugGraphDetails::FULL_PARAMS
337                | crate::DebugGraphDetails::ALL,
338            "\"all+full-params\""
339        );
340        check_deserialize!(
341            crate::DebugGraphDetails,
342            crate::DebugGraphDetails::MEDIA_TYPE
343                | crate::DebugGraphDetails::CAPS_DETAILS
344                | crate::DebugGraphDetails::NON_DEFAULT_PARAMS
345                | crate::DebugGraphDetails::STATES
346                | crate::DebugGraphDetails::FULL_PARAMS,
347            "\"all+full-params\""
348        );
349
350        check_deserialize!(
351            crate::ElementFlags,
352            crate::ElementFlags::all(),
353            "\"locked-state+sink+source+provide-clock+require-clock+indexable\""
354        );
355        check_deserialize!(
356            crate::EventTypeFlags,
357            crate::EventTypeFlags::all(),
358            "\"upstream+downstream+serialized+sticky+sticky-multi\""
359        );
360        #[cfg(feature = "v1_20")]
361        check_deserialize!(crate::GapFlags, crate::GapFlags::all(), "\"data\"");
362        check_deserialize!(
363            crate::MemoryFlags,
364            crate::MemoryFlags::all(),
365            concat!(
366                "\"readonly+no-share+zero-prefixed+zero-padded",
367                "+physically-contiguous+not-mappable\""
368            )
369        );
370        check_deserialize!(
371            crate::MetaFlags,
372            crate::MetaFlags::all(),
373            "\"readonly+pooled+locked\""
374        );
375        check_deserialize!(
376            crate::ObjectFlags,
377            crate::ObjectFlags::all(),
378            "\"may-be-leaked+constructed\""
379        );
380        check_deserialize!(
381            crate::PadFlags,
382            crate::PadFlags::all(),
383            concat!(
384                "\"blocked+flushing+eos+blocking+need-parent+need-reconfigure",
385                "+pending-events+fixed-caps+proxy-caps+proxy-allocation",
386                "+proxy-scheduling+accept-intersect+accept-template\""
387            )
388        );
389        check_deserialize!(
390            crate::PadLinkCheck,
391            crate::PadLinkCheck::all(),
392            "\"hierarchy+template-caps+caps+no-reconfigure\""
393        );
394        check_deserialize!(
395            crate::PadProbeType,
396            crate::PadProbeType::all(),
397            concat!(
398                "\"idle+block+buffer+buffer-list+event-downstream",
399                "+event-upstream+event-flush+query-downstream+query-upstream",
400                "+push+pull\""
401            )
402        );
403        check_deserialize!(
404            crate::ParseFlags,
405            crate::ParseFlags::all(),
406            "\"fatal-errors+no-single-element-bins+place-in-bin\""
407        );
408        #[cfg(feature = "v1_18")]
409        check_deserialize!(
410            crate::PluginAPIFlags,
411            crate::PluginAPIFlags::all(),
412            "\"members\""
413        );
414        check_deserialize!(
415            crate::PluginDependencyFlags,
416            crate::PluginDependencyFlags::all(),
417            concat!(
418                "\"recurse+paths-are-default-only+file-name-is-suffix",
419                "+file-name-is-prefix+paths-are-relative-to-exe\""
420            )
421        );
422        cfg_if::cfg_if! {
423            if #[cfg(feature = "v1_30")] {
424                check_deserialize!(
425                    crate::PluginFlags,
426                    crate::PluginFlags::all(),
427                    "\"cached+blacklisted+static-features\""
428                );
429            } else {
430                check_deserialize!(
431                    crate::PluginFlags,
432                    crate::PluginFlags::all(),
433                    "\"cached+blacklisted\""
434                );
435            }
436        }
437        check_deserialize!(
438            crate::SchedulingFlags,
439            crate::SchedulingFlags::all(),
440            "\"seekable+sequential+bandwidth-limited\""
441        );
442        #[cfg(feature = "v1_18")]
443        check_deserialize!(
444            crate::SeekFlags,
445            crate::SeekFlags::all(),
446            concat!(
447                "\"flush+accurate+key-unit+segment+trickmode+snap-before",
448                "+snap-after+trickmode-key-units+trickmode-no-audio",
449                "+trickmode-forward-predicted+instant-rate-change\""
450            )
451        );
452        #[cfg(feature = "v1_18")]
453        check_deserialize!(
454            crate::SegmentFlags,
455            crate::SegmentFlags::all(),
456            concat!(
457                "\"reset+trickmode+segment+trickmode-key-units",
458                "+trickmode-forward-predicted+trickmode-no-audio\""
459            )
460        );
461        #[cfg(feature = "v1_20")]
462        check_deserialize!(
463            crate::SerializeFlags,
464            crate::SerializeFlags::all(),
465            "\"backward-compat\""
466        );
467        check_deserialize!(
468            crate::StackTraceFlags,
469            crate::StackTraceFlags::all(),
470            "\"full\""
471        );
472        check_deserialize!(
473            crate::StreamFlags,
474            crate::StreamFlags::all(),
475            "\"sparse+select+unselect\""
476        );
477        check_deserialize!(
478            crate::StreamType,
479            crate::StreamType::all(),
480            "\"unknown+audio+video+container+text+metadata\""
481        );
482    }
483
484    #[test]
485    fn test_serde_roundtrip() {
486        crate::init().unwrap();
487
488        check_roundtrip!(crate::BinFlags, crate::BinFlags::empty());
489        check_roundtrip!(crate::BinFlags, crate::BinFlags::all());
490        check_roundtrip!(crate::BufferCopyFlags, crate::BufferCopyFlags::all());
491        check_roundtrip!(crate::BufferFlags, crate::BufferFlags::all());
492        check_roundtrip!(
493            crate::BufferPoolAcquireFlags,
494            crate::BufferPoolAcquireFlags::all()
495        );
496        check_roundtrip!(crate::ClockFlags, crate::ClockFlags::all());
497
498        check_roundtrip!(crate::DebugColorFlags, crate::DebugColorFlags::all());
499        check_roundtrip!(
500            crate::DebugColorFlags,
501            crate::DebugColorFlags::FG_MAGENTA | crate::DebugColorFlags::BOLD
502        );
503        check_roundtrip!(
504            crate::DebugColorFlags,
505            crate::DebugColorFlags::FG_RED
506                | crate::DebugColorFlags::FG_BLUE
507                | crate::DebugColorFlags::BG_BLACK
508        );
509
510        check_roundtrip!(crate::DebugGraphDetails, crate::DebugGraphDetails::all());
511        check_roundtrip!(
512            crate::DebugGraphDetails,
513            crate::DebugGraphDetails::MEDIA_TYPE
514                | crate::DebugGraphDetails::CAPS_DETAILS
515                | crate::DebugGraphDetails::NON_DEFAULT_PARAMS
516                | crate::DebugGraphDetails::STATES
517                | crate::DebugGraphDetails::FULL_PARAMS
518                | crate::DebugGraphDetails::ALL
519        );
520        check_roundtrip!(
521            crate::DebugGraphDetails,
522            crate::DebugGraphDetails::MEDIA_TYPE
523                | crate::DebugGraphDetails::CAPS_DETAILS
524                | crate::DebugGraphDetails::NON_DEFAULT_PARAMS
525                | crate::DebugGraphDetails::STATES
526                | crate::DebugGraphDetails::FULL_PARAMS
527        );
528
529        check_roundtrip!(crate::ElementFlags, crate::ElementFlags::all());
530        check_roundtrip!(crate::EventTypeFlags, crate::EventTypeFlags::all());
531        #[cfg(feature = "v1_20")]
532        check_roundtrip!(crate::GapFlags, crate::GapFlags::all());
533        check_roundtrip!(crate::MemoryFlags, crate::MemoryFlags::all());
534        check_roundtrip!(crate::MetaFlags, crate::MetaFlags::all());
535        check_roundtrip!(crate::ObjectFlags, crate::ObjectFlags::all());
536        check_roundtrip!(crate::PadFlags, crate::PadFlags::all());
537        check_roundtrip!(crate::PadLinkCheck, crate::PadLinkCheck::all());
538        check_roundtrip!(crate::PadProbeType, crate::PadProbeType::all());
539        check_roundtrip!(crate::ParseFlags, crate::ParseFlags::all());
540        #[cfg(feature = "v1_18")]
541        check_roundtrip!(crate::PluginAPIFlags, crate::PluginAPIFlags::all());
542        check_roundtrip!(
543            crate::PluginDependencyFlags,
544            crate::PluginDependencyFlags::all()
545        );
546        check_roundtrip!(crate::PluginFlags, crate::PluginFlags::all());
547        check_roundtrip!(crate::SchedulingFlags, crate::SchedulingFlags::all());
548        #[cfg(feature = "v1_18")]
549        check_roundtrip!(crate::SeekFlags, crate::SeekFlags::all());
550        #[cfg(feature = "v1_18")]
551        check_roundtrip!(crate::SegmentFlags, crate::SegmentFlags::all());
552        #[cfg(feature = "v1_20")]
553        check_roundtrip!(crate::SerializeFlags, crate::SerializeFlags::all());
554        check_roundtrip!(crate::StackTraceFlags, crate::StackTraceFlags::all());
555        check_roundtrip!(crate::StreamFlags, crate::StreamFlags::all());
556        check_roundtrip!(crate::StreamType, crate::StreamType::all());
557    }
558}