ffmpeg_the_third/util/dictionary/
immutable.rs

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