ffmpeg_the_third/util/dictionary/impls.rs
1use std::ffi::CString;
2
3use super::{Dictionary, DictionaryMut, DictionaryRef};
4use super::{Flags, Iter};
5use crate::ffi::*;
6use crate::macros::impl_for_many;
7use crate::utils;
8
9pub fn set(dict: &mut *mut AVDictionary, key: &str, value: &str, flags: Flags) {
10 let key = CString::new(key).unwrap();
11 let value = CString::new(value).unwrap();
12
13 unsafe {
14 if av_dict_set(dict, key.as_ptr(), value.as_ptr(), flags.bits()) < 0 {
15 panic!("out of memory");
16 }
17 }
18}
19
20pub fn unset(dict: &mut *mut AVDictionary, key: &str, flags: Flags) {
21 let key = CString::new(key).unwrap();
22
23 unsafe {
24 av_dict_set(dict, key.as_ptr(), std::ptr::null(), flags.bits());
25 }
26}
27
28// Safety: Ensure the returned lifetime 'd is bounded to a borrow on dict
29pub unsafe fn get<'d>(dict: *const AVDictionary, key: &str, flags: Flags) -> Option<&'d str> {
30 let key = CString::new(key).unwrap();
31 unsafe {
32 let entry = av_dict_get(dict, key.as_ptr(), std::ptr::null_mut(), flags.bits());
33
34 if entry.is_null() {
35 None
36 } else {
37 Some(utils::str_from_c_ptr((*entry).value))
38 }
39 }
40}
41
42impl_for_many! {
43 impl for Dictionary, DictionaryRef<'a>, DictionaryMut<'a> {
44 /// Try to find a value in the dictionary.
45 ///
46 /// This function uses case-insensitive matching of the entire key string
47 /// to find a value. If you want to customize the way FFmpeg searches
48 /// for the key, see [`get_with_flags`][Self::get_with_flags].
49 pub fn get<K: AsRef<str>>(&self, key: K) -> Option<&str> {
50 self.get_with_flags(key, Flags::empty())
51 }
52
53 /// Try to find a value in the dictionary, using custom search flags.
54 ///
55 /// See [Flags][crate::dictionary::Flags] to see how each flag works.
56 /// Using [`Flags::DONT_STRDUP_KEY`] is heavily discouraged unless you
57 /// know what you are doing.
58 pub fn get_with_flags<K: AsRef<str>>(&self, key: K, flags: Flags) -> Option<&str> {
59 // SAFETY: Returned lifetime is bounded by borrow on self
60 unsafe { get(self.as_ptr(), key.as_ref(), flags) }
61 }
62
63 /// Returns the number of entries in the dictionary.
64 pub fn len(&self) -> usize {
65 unsafe { av_dict_count(self.as_ptr()) as usize }
66 }
67
68 /// Returns `true` if the dictionary is empty.
69 pub fn is_empty(&self) -> bool {
70 self.as_ptr().is_null()
71 }
72
73 /// Creates an iterator over all key-value pairs in the dictionary.
74 pub fn iter(&self) -> Iter<'_> {
75 Iter::new(self.as_ptr())
76 }
77 }
78}
79
80impl_for_many! {
81 impl for Dictionary, DictionaryMut<'a> {
82 /// Set a value for the given key.
83 ///
84 /// This function will overwrite any value that already exists
85 /// for the given key. If you want to customize the way FFmpeg inserts
86 /// the new value, see [`set_with_flags`][Self::set_with_flags].
87 pub fn set<K, V>(&mut self, key: K, value: V)
88 where
89 K: AsRef<str>,
90 V: AsRef<str>,
91 {
92 self.set_with_flags(key, value, Flags::empty())
93 }
94
95 /// Set a value for the given key, using custom flags.
96 ///
97 /// See [Flags][crate::dictionary::Flags] to see how each flag works.
98 /// Using [`Flags::DONT_STRDUP_KEY`] or [`Flags::DONT_STRDUP_VAL`] is
99 /// heavily discouraged unless you know what you are doing.
100 pub fn set_with_flags<K, V>(&mut self, key: K, value: V, flags: Flags)
101 where
102 K: AsRef<str>,
103 V: AsRef<str>,
104 {
105 set(self.as_mut_ptr(), key.as_ref(), value.as_ref(), flags)
106 }
107
108 /// Remove a value from the dictionary for the given key.
109 ///
110 /// If you want to customize the way FFmpeg searches for the key,
111 /// see [`unset_with_flags`][Self::unset_with_flags].
112 pub fn unset<K: AsRef<str>>(&mut self, key: K) {
113 self.unset_with_flags(key, Flags::empty());
114 }
115
116 /// Remove a value from the dictionary for the given key, using custom flags.
117 ///
118 /// See [Flags][crate::dictionary::Flags] to see how each flag works.
119 /// Using [`Flags::DONT_STRDUP_KEY`] or [`Flags::DONT_STRDUP_VAL`] is
120 /// heavily discouraged unless you know what you are doing.
121 pub fn unset_with_flags<K: AsRef<str>>(&mut self, key: K, flags: Flags) {
122 unset(self.as_mut_ptr(), key.as_ref(), flags);
123 }
124 }
125}
126
127impl_for_many! {
128 impl for DictionaryRef<'d>, DictionaryMut<'d> {
129 /// Clones the borrowed data into an owned [Dictionary].
130 pub fn to_owned(&self) -> Dictionary {
131 self.iter().collect()
132 }
133 }
134}