Skip to main content

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}