gstreamer/id_str/
mod.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! This module selects one of the two `IdStr` implementations:
5//!
6//! * When feature `v1_26` (or later) is activated, `IdStr` implements the bindings
7//!   for the C type `GstIdStr`.
8//! * For earlier feature versions, a compatibility implementation is used.
9//!
10//! See also: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7432>
11
12cfg_if::cfg_if! {
13    if #[cfg(feature = "v1_26")] {
14        mod bindings;
15        pub use self::bindings::IdStr;
16    } else {
17        mod compat;
18        pub use self::compat::IdStr;
19    }
20}
21
22#[cfg(feature = "serde")]
23mod serde;
24
25// rustdoc-stripper-ignore-next
26/// Builds an [`IdStr`] from a string literal.
27///
28/// # Examples
29///
30/// ```
31/// # fn main() {
32/// use gstreamer::{idstr, IdStr};
33/// use std::sync::LazyLock;
34///
35/// static MY_ID_STR: LazyLock<IdStr> = LazyLock::new(|| idstr!("static id"));
36/// assert_eq!(*MY_ID_STR, "static id");
37///
38/// let my_id_str: IdStr = idstr!("local id");
39/// assert_eq!(my_id_str, "local id");
40/// # }
41/// ```
42///
43/// [`IdStr`]: crate::IdStr
44#[macro_export]
45macro_rules! idstr {
46    ($s:literal) => {
47        IdStr::from_static($crate::glib::gstr!($s))
48    };
49}
50
51#[cfg(test)]
52mod tests {
53    use glib::{gstr, GStr, GString};
54    use std::{ffi::CStr, sync::LazyLock};
55
56    use super::IdStr;
57
58    const STR: &str = "STR";
59    static IDSTR: LazyLock<IdStr> = LazyLock::new(|| idstr!("IDSTR"));
60    static GSTR: &GStr = gstr!("GSTR");
61    static GSTRING: LazyLock<GString> = LazyLock::new(|| GString::from("GSTRING"));
62
63    const LONG_STR: &str = "An STR longer than 15 bytes";
64    static LONG_IDSTR: LazyLock<IdStr> = LazyLock::new(|| idstr!("An IdStr longer than 15 bytes"));
65    static LONG_GSTR: &GStr = gstr!("A GSTR longer than 15 bytes");
66    static LONG_GSTRING: LazyLock<GString> =
67        LazyLock::new(|| GString::from("A GSTRING longer than 15 bytes"));
68
69    #[test]
70    fn new_set_static() {
71        assert!(!IDSTR.is_empty());
72        assert_eq!(IDSTR.len(), "IDSTR".len());
73        assert_eq!(IDSTR.as_str().len(), "IDSTR".len());
74        assert_eq!(*IDSTR, "IDSTR");
75        // Display impl
76        assert_eq!(IDSTR.to_string(), "IDSTR");
77        assert_eq!(IDSTR.as_str(), "IDSTR");
78        assert_eq!(IDSTR.as_gstr().len(), "IDSTR".len());
79        assert_eq!(IDSTR.as_gstr(), "IDSTR");
80
81        let id_str: IdStr = idstr!("id_str");
82        assert!(!id_str.is_empty());
83        assert_eq!(id_str.len(), "id_str".len());
84        assert_eq!(id_str.as_str().len(), "id_str".len());
85        assert_eq!(id_str, "id_str");
86
87        let mut s = IdStr::new();
88        assert!(s.is_empty());
89        assert_eq!(s.len(), 0);
90        assert_eq!(s.as_str(), "");
91        assert_eq!(s.as_gstr(), "");
92
93        s.set_static(gstr!("str"));
94        assert!(!s.is_empty());
95        assert_eq!(s.len(), "str".len());
96        assert_eq!(s.as_str().len(), "str".len());
97        assert_eq!(s, "str");
98        // Display impl
99        assert_eq!(s.to_string(), "str");
100        assert_eq!(s.as_str(), "str");
101        assert_eq!(s.as_gstr().len(), "str".len());
102        assert_eq!(s.as_gstr(), "str");
103
104        s.set_static(GSTR);
105        assert_eq!(s.as_str(), "GSTR");
106
107        s.set_static(&*GSTRING);
108        assert_eq!(s.as_str(), "GSTRING");
109
110        assert!(!LONG_IDSTR.is_empty());
111        assert_eq!(LONG_IDSTR.len(), "An IdStr longer than 15 bytes".len());
112        assert_eq!(*LONG_IDSTR, "An IdStr longer than 15 bytes");
113        // Display impl
114        assert_eq!(LONG_IDSTR.to_string(), "An IdStr longer than 15 bytes");
115        assert_eq!(
116            LONG_IDSTR.as_str().len(),
117            "An IdStr longer than 15 bytes".len()
118        );
119        assert_eq!(LONG_IDSTR.as_str(), "An IdStr longer than 15 bytes");
120        assert_eq!(
121            LONG_IDSTR.as_gstr().len(),
122            "An IdStr longer than 15 bytes".len()
123        );
124        assert_eq!(LONG_IDSTR.as_gstr(), "An IdStr longer than 15 bytes");
125
126        let ls = idstr!("An IdStr longer than 15 bytes");
127        assert!(!ls.is_empty());
128        assert_eq!(ls.len(), "An IdStr longer than 15 bytes".len());
129        assert_eq!(ls, "An IdStr longer than 15 bytes");
130
131        let mut ls = IdStr::new();
132
133        ls.set_static(gstr!("An str longer than 15 bytes"));
134        assert!(!ls.is_empty());
135        assert_eq!(ls.len(), "An str longer than 15 bytes".len());
136        assert_eq!(ls, "An str longer than 15 bytes");
137
138        ls.set_static(LONG_GSTR);
139        assert_eq!(ls.as_str(), "A GSTR longer than 15 bytes");
140
141        ls.set_static(&*LONG_GSTRING);
142        assert_eq!(ls.as_str(), "A GSTRING longer than 15 bytes");
143    }
144
145    #[test]
146    fn from_static() {
147        let s = IdStr::from_static(gstr!("str"));
148        assert!(!s.is_empty());
149        assert_eq!(s.len(), "str".len());
150        assert_eq!(s.as_str().len(), "str".len());
151        assert_eq!(s, "str");
152        // Display impl
153        assert_eq!(s.to_string(), "str");
154        assert_eq!(s.as_str(), "str");
155        assert_eq!(s.as_gstr().len(), "str".len());
156        assert_eq!(s.as_gstr(), "str");
157
158        let s = idstr!("str");
159        assert!(!s.is_empty());
160        assert_eq!(s.len(), "str".len());
161        assert_eq!(s.as_str().len(), "str".len());
162        assert_eq!(s, "str");
163
164        let s = IdStr::from_static(GSTR);
165        assert_eq!(s.as_str(), "GSTR");
166
167        let s = IdStr::from_static(&*GSTRING);
168        assert_eq!(s.as_str(), "GSTRING");
169
170        let ls = IdStr::from_static(gstr!("An str longer than 15 bytes"));
171        assert!(!ls.is_empty());
172        assert_eq!(ls.len(), "An str longer than 15 bytes".len());
173        assert_eq!(ls, "An str longer than 15 bytes");
174        // Display impl
175        assert_eq!(ls.to_string(), "An str longer than 15 bytes");
176        assert_eq!(ls.as_str().len(), "An str longer than 15 bytes".len());
177        assert_eq!(ls.as_str(), "An str longer than 15 bytes");
178        assert_eq!(ls.as_gstr().len(), "An str longer than 15 bytes".len());
179        assert_eq!(ls.as_gstr(), "An str longer than 15 bytes");
180
181        let ls = idstr!("An str longer than 15 bytes");
182        assert!(!ls.is_empty());
183        assert_eq!(ls.len(), "An str longer than 15 bytes".len());
184        assert_eq!(ls, "An str longer than 15 bytes");
185
186        let ls = IdStr::from_static(LONG_GSTR);
187        assert_eq!(ls.as_str(), "A GSTR longer than 15 bytes");
188
189        let ls = IdStr::from_static(&*LONG_GSTRING);
190        assert_eq!(ls.as_str(), "A GSTRING longer than 15 bytes");
191    }
192
193    #[test]
194    fn new_set() {
195        let d = IdStr::default();
196        assert!(d.is_empty());
197        assert_eq!(d.len(), 0);
198        assert_eq!(d.as_str(), "");
199        assert_eq!(d.as_gstr(), "");
200
201        let mut s = IdStr::new();
202        assert!(s.is_empty());
203        assert_eq!(s.len(), 0);
204        assert_eq!(s.as_str(), "");
205        assert_eq!(s.as_gstr(), "");
206
207        s.set("str");
208        assert!(!s.is_empty());
209        assert_eq!(s.len(), "str".len());
210        assert_eq!(s.as_str().len(), "str".len());
211        assert_eq!(s.as_str(), "str");
212        assert_eq!(AsRef::<str>::as_ref(&s), "str");
213        // Display impl
214        assert_eq!(s.to_string(), "str");
215        assert_eq!(s.as_gstr().len(), "str".len());
216        assert_eq!(s.as_gstr(), "str");
217        assert_eq!(AsRef::<GStr>::as_ref(&s), "str");
218        assert_eq!(s.as_cstr().to_bytes(), b"str");
219        assert_eq!(AsRef::<CStr>::as_ref(&s).to_bytes(), b"str");
220        assert_eq!(s.as_bytes(), b"str");
221
222        let string = String::from("String");
223        s.set(string.as_str());
224        assert_eq!(s.as_str(), "String");
225        s.set(&string);
226        assert_eq!(s.as_str(), "String");
227
228        s.set(gstr!("gstr"));
229        assert_eq!(s.as_str(), "gstr");
230
231        let gstring = GString::from("GString");
232        s.set(gstring.as_gstr());
233        assert_eq!(s.as_str(), "GString");
234        s.set(&gstring);
235        assert_eq!(s.as_str(), "GString");
236        s.set(gstring.as_str());
237        assert_eq!(s.as_str(), "GString");
238
239        let mut ls = IdStr::new();
240
241        ls.set("An str longer than 15 bytes");
242        assert!(!ls.is_empty());
243        assert_eq!(ls.len(), "An str longer than 15 bytes".len());
244        assert_eq!(ls, "An str longer than 15 bytes");
245        // Display impl
246        assert_eq!(ls.to_string(), "An str longer than 15 bytes");
247        assert_eq!(ls.as_str().len(), "An str longer than 15 bytes".len());
248        assert_eq!(ls.as_str(), "An str longer than 15 bytes");
249        assert_eq!(ls.as_gstr().len(), "An str longer than 15 bytes".len());
250        assert_eq!(ls.as_gstr(), "An str longer than 15 bytes");
251        assert_eq!(ls.as_cstr().to_bytes(), b"An str longer than 15 bytes");
252        assert_eq!(
253            AsRef::<CStr>::as_ref(&ls).to_bytes(),
254            b"An str longer than 15 bytes"
255        );
256        assert_eq!(ls.as_bytes(), b"An str longer than 15 bytes");
257
258        ls.set(gstr!("A gstr longer than 15 bytes"));
259        assert_eq!(ls.as_str(), "A gstr longer than 15 bytes");
260    }
261
262    #[test]
263    fn from() {
264        let s = IdStr::from("str");
265        assert_eq!(s.len(), "str".len());
266        assert_eq!(s.as_str().len(), "str".len());
267        assert_eq!(s.as_str(), "str");
268        // Display impl
269        assert_eq!(s.to_string(), "str");
270        assert_eq!(s.as_gstr().len(), "str".len());
271        assert_eq!(s.as_gstr(), "str");
272
273        let string = String::from("String");
274        let s = IdStr::from(string.as_str());
275        assert_eq!(s.as_str(), "String");
276        let s: IdStr = string.as_str().into();
277        assert_eq!(s.as_str(), "String");
278        let s: IdStr = (&string).into();
279        assert_eq!(s.as_str(), "String");
280        let s: IdStr = string.into();
281        assert_eq!(s.as_str(), "String");
282
283        let s = IdStr::from(gstr!("str"));
284        assert_eq!(s.as_str(), "str");
285
286        let gstring = GString::from("GString");
287        let s = IdStr::from(gstring.as_gstr());
288        assert_eq!(s.as_str(), "GString");
289        let s: IdStr = (&gstring).into();
290        assert_eq!(s.as_str(), "GString");
291        let s: IdStr = gstring.into();
292        assert_eq!(s.as_str(), "GString");
293
294        let ls = IdStr::from("An str longer than 15 bytes");
295        assert!(!ls.is_empty());
296        assert_eq!(ls.len(), "An str longer than 15 bytes".len());
297        assert_eq!(ls, "An str longer than 15 bytes");
298        // Display impl
299        assert_eq!(ls.to_string(), "An str longer than 15 bytes");
300        assert_eq!(ls.as_str().len(), "An str longer than 15 bytes".len());
301        assert_eq!(ls.as_str(), "An str longer than 15 bytes");
302        assert_eq!(ls.as_gstr().len(), "An str longer than 15 bytes".len());
303        assert_eq!(ls.as_gstr(), "An str longer than 15 bytes");
304
305        let ls = IdStr::from(gstr!("A gstr longer than 15 bytes"));
306        assert_eq!(ls.as_str(), "A gstr longer than 15 bytes");
307        assert_eq!(ls.as_gstr(), "A gstr longer than 15 bytes");
308
309        let lstring = String::from("A String longer than 15 bytes");
310        let ls = IdStr::from(lstring.as_str());
311        assert_eq!(ls.as_str(), "A String longer than 15 bytes");
312        let ls = IdStr::from(&lstring);
313        assert_eq!(ls.as_str(), "A String longer than 15 bytes");
314
315        let lgstring = String::from("A GString longer than 15 bytes");
316        let ls = IdStr::from(lgstring.as_str());
317        assert_eq!(ls.as_str(), "A GString longer than 15 bytes");
318        let ls = IdStr::from(&lgstring);
319        assert_eq!(ls.as_str(), "A GString longer than 15 bytes");
320    }
321
322    #[test]
323    #[allow(clippy::cmp_owned)]
324    fn eq_cmp() {
325        let s1 = IdStr::from(STR);
326        let s12: IdStr = STR.into();
327        assert_eq!(s1, s12);
328        let s2 = IdStr::from(String::from(STR));
329        let s22: IdStr = String::from(STR).into();
330        assert_eq!(s2, s22);
331        let s3 = IdStr::from_static(gstr!("STR"));
332        assert_eq!(s1, s2);
333        assert_eq!(s1, s3);
334        assert_eq!(s2, s3);
335
336        assert!(s1 == gstr!("STR"));
337        assert_eq!(s1, gstr!("STR"));
338        assert_eq!(s1, GString::from("STR"));
339        assert!(s1 == "STR");
340        assert_eq!(s1, "STR");
341        assert!("STR" == s1);
342        assert_eq!("STR", s1);
343        assert_eq!(s1, String::from("STR"));
344
345        assert_eq!(gstr!("STR"), s1);
346        assert_eq!(GString::from("STR"), s1);
347        assert_eq!("STR", s1);
348        assert_eq!(String::from("STR"), s1);
349
350        let ls1 = IdStr::from(LONG_STR);
351        let ls2: IdStr = String::from(LONG_STR).into();
352        let ls3 = IdStr::from_static(gstr!("An STR longer than 15 bytes"));
353        assert_eq!(ls1, ls2);
354        assert_eq!(ls1, ls3);
355        assert_eq!(ls2, ls3);
356
357        assert!(ls1 == gstr!("An STR longer than 15 bytes"));
358        assert_eq!(ls1, gstr!("An STR longer than 15 bytes"));
359        assert_eq!(ls1, GString::from(LONG_STR));
360        assert_eq!(ls1, LONG_STR);
361        assert!(ls1 == "An STR longer than 15 bytes");
362        assert_eq!(ls1, "An STR longer than 15 bytes");
363        assert_eq!(ls1, String::from(LONG_STR));
364
365        assert_eq!(gstr!("An STR longer than 15 bytes"), ls1);
366        assert_eq!(GString::from(LONG_STR), ls1);
367        assert_eq!(LONG_STR, ls1);
368        assert_eq!("An STR longer than 15 bytes", ls1);
369        assert_eq!(String::from(LONG_STR), ls1);
370
371        assert_ne!(s1, ls1);
372        assert_ne!(ls1, s1);
373
374        let s4 = IdStr::from("STR4");
375        assert_ne!(s1, s4);
376        assert!(s1 < s4);
377        assert!(s4 > s1);
378
379        assert!(s1 < gstr!("STR4"));
380        assert!(s1 < GString::from("STR4"));
381        assert!(s1 < "STR4");
382        assert!("STR4" > s1);
383        assert!(s1 < String::from("STR4"));
384
385        assert!(gstr!("STR4") > s1);
386        assert!(GString::from("STR4") > s1);
387        assert!("STR4" > s1);
388        assert!(String::from("STR4") > s1);
389
390        // ls1 starts with an 'A', s4 with an 'S'
391        assert_ne!(ls1, s4);
392        assert!(ls1 < s4);
393        assert!(s4 > s1);
394    }
395
396    #[test]
397    fn as_ref_idstr() {
398        #[allow(clippy::nonminimal_bool)]
399        fn check(c: &str, v: impl AsRef<IdStr>) {
400            let v = v.as_ref();
401
402            assert_eq!(c, v);
403            assert_eq!(v, c);
404
405            assert!(!(c > v));
406            assert!(!(v > c));
407
408            let i = IdStr::from(c);
409            assert_eq!(i, v);
410            assert_eq!(i, IdStr::from(c));
411
412            assert!(!(c > i));
413            assert!(!(i > c));
414        }
415
416        let v = IdStr::from(STR);
417        check(STR, &v);
418        check(STR, v);
419
420        #[allow(clippy::nonminimal_bool)]
421        fn check_gstr(c: &GStr, v: impl AsRef<IdStr>) {
422            let v = v.as_ref();
423
424            assert_eq!(c, v);
425            assert_eq!(v, c);
426
427            assert!(!(c > v));
428            assert!(!(v > c));
429        }
430
431        let v = IdStr::from(GSTR);
432        check_gstr(GSTR, &v);
433        check_gstr(GSTR, v);
434    }
435}