1 | use std::ffi::{CStr, CString}; |
2 | use std::fmt; |
3 | use std::marker::PhantomData; |
4 | use std::ptr; |
5 | use std::str::from_utf8_unchecked; |
6 | |
7 | use super::{Iter, Owned}; |
8 | use ffi::*; |
9 | |
10 | pub struct Ref<'a> { |
11 | ptr: *const AVDictionary, |
12 | |
13 | _marker: PhantomData<&'a ()>, |
14 | } |
15 | |
16 | impl<'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 | |
29 | impl<'a> Ref<'a> { |
30 | pub fn get(&'a self, key: &str) -> Option<&'a str> { |
31 | unsafe { |
32 | let key: CString = 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 | |
54 | impl<'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 | |
63 | impl<'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 | } |
68 | |