playa_ffmpeg/util/dictionary/
immutable.rs

1use std::{
2    ffi::{CStr, CString},
3    fmt,
4    marker::PhantomData,
5    ptr,
6    str::from_utf8_unchecked,
7};
8
9use super::{Iter, Owned};
10use crate::ffi::*;
11
12pub struct Ref<'a> {
13    ptr: *const AVDictionary,
14
15    _marker: PhantomData<&'a ()>,
16}
17
18impl<'a> Ref<'a> {
19    pub unsafe fn wrap(ptr: *const AVDictionary) -> Self {
20        Ref { ptr, _marker: PhantomData }
21    }
22
23    pub unsafe fn as_ptr(&self) -> *const AVDictionary {
24        self.ptr
25    }
26}
27
28impl<'a> Ref<'a> {
29    pub fn get(&'a self, key: &str) -> Option<&'a str> {
30        unsafe {
31            let key = CString::new(key).unwrap();
32            let entry = av_dict_get(self.as_ptr(), key.as_ptr(), ptr::null_mut(), 0);
33
34            if entry.is_null() { None } else { Some(from_utf8_unchecked(CStr::from_ptr((*entry).value).to_bytes())) }
35        }
36    }
37
38    pub fn iter(&self) -> Iter<'_> {
39        unsafe { Iter::new(self.as_ptr()) }
40    }
41
42    pub fn to_owned<'b>(&self) -> Owned<'b> {
43        self.iter().collect()
44    }
45}
46
47impl<'a> IntoIterator for &'a Ref<'a> {
48    type Item = (&'a str, &'a str);
49    type IntoIter = Iter<'a>;
50
51    fn into_iter(self) -> Self::IntoIter {
52        self.iter()
53    }
54}
55
56impl<'a> fmt::Debug for Ref<'a> {
57    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
58        fmt.debug_map().entries(self.iter()).finish()
59    }
60}