1use 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}