vapoursynth/map/
mod.rs

1//! VapourSynth maps.
2
3use std::borrow::Cow;
4use std::ffi::{CStr, CString};
5use std::marker::PhantomData;
6use std::ops::{Deref, DerefMut};
7use std::ptr::NonNull;
8use std::{result, slice};
9use vapoursynth_sys as ffi;
10
11use crate::api::API;
12use crate::frame::{Frame, FrameRef};
13use crate::function::Function;
14use crate::node::Node;
15
16mod errors;
17pub use self::errors::{Error, InvalidKeyError, Result};
18
19mod iterators;
20pub use self::iterators::{Keys, ValueIter};
21
22mod value;
23pub use self::value::{Value, ValueType};
24
25/// A VapourSynth map.
26///
27/// A map contains key-value pairs where the value is zero or more elements of a certain type.
28// This type is intended to be publicly used only in reference form.
29#[derive(Debug)]
30pub struct Map<'elem> {
31    // The actual mutability of this depends on whether it's accessed via `&Map` or `&mut Map`.
32    handle: NonNull<ffi::VSMap>,
33    _elem: PhantomData<&'elem ()>,
34}
35
36/// A reference to a VapourSynth map.
37#[derive(Debug)]
38pub struct MapRef<'owner, 'elem> {
39    // Only immutable references to this are allowed.
40    map: Map<'elem>,
41    _owner: PhantomData<&'owner ()>,
42}
43
44/// A reference to a mutable VapourSynth map.
45#[derive(Debug)]
46pub struct MapRefMut<'owner, 'elem> {
47    // Both mutable and immutable references to this are allowed.
48    map: Map<'elem>,
49    _owner: PhantomData<&'owner ()>,
50}
51
52/// An owned VapourSynth map.
53#[derive(Debug)]
54pub struct OwnedMap<'elem> {
55    // Both mutable and immutable references to this are allowed.
56    map: Map<'elem>,
57}
58
59unsafe impl<'elem> Send for Map<'elem> {}
60unsafe impl<'elem> Sync for Map<'elem> {}
61
62#[doc(hidden)]
63impl<'elem> Deref for Map<'elem> {
64    type Target = ffi::VSMap;
65
66    #[inline]
67    fn deref(&self) -> &Self::Target {
68        unsafe { self.handle.as_ref() }
69    }
70}
71
72#[doc(hidden)]
73impl<'elem> DerefMut for Map<'elem> {
74    #[inline]
75    fn deref_mut(&mut self) -> &mut Self::Target {
76        unsafe { self.handle.as_mut() }
77    }
78}
79
80impl<'owner, 'elem> Deref for MapRef<'owner, 'elem> {
81    type Target = Map<'elem>;
82
83    // Technically this should return `&'owner`.
84    #[inline]
85    fn deref(&self) -> &Self::Target {
86        &self.map
87    }
88}
89
90impl<'owner, 'elem> Deref for MapRefMut<'owner, 'elem> {
91    type Target = Map<'elem>;
92
93    // Technically this should return `&'owner`.
94    #[inline]
95    fn deref(&self) -> &Self::Target {
96        &self.map
97    }
98}
99
100impl<'owner, 'elem> DerefMut for MapRefMut<'owner, 'elem> {
101    // Technically this should return `&'owner`.
102    #[inline]
103    fn deref_mut(&mut self) -> &mut Self::Target {
104        &mut self.map
105    }
106}
107
108impl<'elem> Drop for OwnedMap<'elem> {
109    #[inline]
110    fn drop(&mut self) {
111        unsafe {
112            API::get_cached().free_map(&mut self.map);
113        }
114    }
115}
116
117impl<'elem> Deref for OwnedMap<'elem> {
118    type Target = Map<'elem>;
119
120    #[inline]
121    fn deref(&self) -> &Self::Target {
122        &self.map
123    }
124}
125
126impl<'elem> DerefMut for OwnedMap<'elem> {
127    #[inline]
128    fn deref_mut(&mut self) -> &mut Self::Target {
129        &mut self.map
130    }
131}
132
133impl<'elem> OwnedMap<'elem> {
134    /// Creates a new map.
135    #[inline]
136    pub fn new(api: API) -> Self {
137        Self {
138            map: unsafe { Map::from_ptr(api.create_map()) },
139        }
140    }
141
142    /// Wraps pointer into `OwnedMap`.
143    ///
144    /// # Safety
145    /// The caller needs to ensure the pointer and the lifetime is valid and that this is an owned
146    /// map pointer.
147    #[inline]
148    pub(crate) unsafe fn from_ptr(handle: *mut ffi::VSMap) -> Self {
149        Self {
150            map: unsafe { Map::from_ptr(handle) },
151        }
152    }
153}
154
155impl<'owner, 'elem> MapRef<'owner, 'elem> {
156    /// Wraps pointer into `MapRef`.
157    ///
158    /// # Safety
159    /// The caller needs to ensure the pointer and the lifetimes are valid, and that there are no
160    /// mutable references to the given map.
161    #[inline]
162    pub(crate) unsafe fn from_ptr(handle: *const ffi::VSMap) -> Self {
163        Self {
164            map: unsafe { Map::from_ptr(handle) },
165            _owner: PhantomData,
166        }
167    }
168}
169
170impl<'owner, 'elem> MapRefMut<'owner, 'elem> {
171    /// Wraps pointer into `MapRefMut`.
172    ///
173    /// # Safety
174    /// The caller needs to ensure the pointer and the lifetimes are valid, and that there are no
175    /// references to the given map.
176    #[inline]
177    pub(crate) unsafe fn from_ptr(handle: *mut ffi::VSMap) -> Self {
178        Self {
179            map: unsafe { Map::from_ptr(handle) },
180            _owner: PhantomData,
181        }
182    }
183}
184
185/// Turns a `prop_get_something()` error into a `Result`.
186#[inline]
187fn handle_get_prop_error(error: i32) -> Result<()> {
188    if error == 0 {
189        Ok(())
190    } else {
191        Err(match error {
192            x if x == ffi::VSMapPropertyError_peUnset as i32 => Error::KeyNotFound,
193            x if x == ffi::VSMapPropertyError_peType as i32 => Error::WrongValueType,
194            x if x == ffi::VSMapPropertyError_peIndex as i32 => Error::IndexOutOfBounds,
195            _ => Error::UnknownError,
196        })
197    }
198}
199
200/// Turns a `prop_set_something(paAppend)` error into a `Result`.
201#[inline]
202fn handle_append_prop_error(error: i32) -> Result<()> {
203    if error != 0 {
204        debug_assert!(error == 1);
205        Err(Error::WrongValueType)
206    } else {
207        Ok(())
208    }
209}
210
211impl<'elem> Map<'elem> {
212    /// Wraps pointer into `Map`.
213    ///
214    /// # Safety
215    /// The caller needs to ensure the pointer is valid, the element lifetime is valid, and that
216    /// the resulting `Map` gets put into `MapRef` or `MapRefMut` or `OwnedMap` correctly.
217    #[inline]
218    pub(crate) unsafe fn from_ptr(handle: *const ffi::VSMap) -> Self {
219        Self {
220            handle: unsafe { NonNull::new_unchecked(handle as *mut ffi::VSMap) },
221            _elem: PhantomData,
222        }
223    }
224
225    /// Checks if the key is valid. Valid keys start with an alphabetic character or an underscore,
226    /// and contain only alphanumeric characters and underscores.
227    pub fn is_key_valid(key: &str) -> result::Result<(), InvalidKeyError> {
228        if key.is_empty() {
229            return Err(InvalidKeyError::EmptyKey);
230        }
231
232        let mut chars = key.chars();
233
234        let first = chars.next().unwrap();
235        if !first.is_ascii_alphabetic() && first != '_' {
236            return Err(InvalidKeyError::InvalidCharacter(0));
237        }
238
239        for (i, c) in chars.enumerate() {
240            if !c.is_ascii_alphanumeric() && c != '_' {
241                return Err(InvalidKeyError::InvalidCharacter(i + 1));
242            }
243        }
244
245        Ok(())
246    }
247
248    /// Checks if the key is valid and makes it a `CString`.
249    #[inline]
250    pub(crate) fn make_raw_key(key: &str) -> Result<CString> {
251        Map::is_key_valid(key)?;
252        Ok(CString::new(key).unwrap())
253    }
254
255    /// Clears the map.
256    #[inline]
257    pub fn clear(&mut self) {
258        unsafe {
259            API::get_cached().clear_map(self);
260        }
261    }
262
263    /// Returns the error message contained in the map, if any.
264    #[inline]
265    pub fn error(&self) -> Option<Cow<'_, str>> {
266        let error_message = unsafe { API::get_cached().get_error(self) };
267        if error_message.is_null() {
268            return None;
269        }
270
271        let error_message = unsafe { CStr::from_ptr(error_message) };
272        Some(error_message.to_string_lossy())
273    }
274
275    /// Adds an error message to a map. The map is cleared first.
276    #[inline]
277    pub fn set_error(&mut self, error_message: &str) -> Result<()> {
278        let error_message = CString::new(error_message)?;
279        unsafe {
280            API::get_cached().set_error(self, error_message.as_ptr());
281        }
282        Ok(())
283    }
284
285    /// Returns the number of keys contained in a map.
286    #[inline]
287    pub fn key_count(&self) -> usize {
288        let count = unsafe { API::get_cached().prop_num_keys(self) };
289        debug_assert!(count >= 0);
290        count as usize
291    }
292
293    /// Returns a key from a map.
294    ///
295    /// # Panics
296    /// Panics if `index >= self.key_count()`.
297    #[inline]
298    pub(crate) fn key_raw(&self, index: usize) -> &CStr {
299        assert!(index < self.key_count());
300        let index = index as i32;
301
302        unsafe { CStr::from_ptr(API::get_cached().prop_get_key(self, index)) }
303    }
304
305    /// Returns a key from a map.
306    ///
307    /// # Panics
308    /// Panics if `index >= self.key_count()`.
309    #[inline]
310    pub fn key(&self, index: usize) -> &str {
311        self.key_raw(index).to_str().unwrap()
312    }
313
314    /// Returns an iterator over all keys in a map.
315    #[inline]
316    pub fn keys(&self) -> Keys<'_, '_> {
317        Keys::new(self)
318    }
319
320    /// Returns the number of elements associated with a key in a map.
321    ///
322    /// # Safety
323    /// The caller must ensure `key` is valid.
324    #[inline]
325    pub(crate) unsafe fn value_count_raw_unchecked(&self, key: &CStr) -> Result<usize> {
326        let rv = unsafe { API::get_cached().prop_num_elements(self, key.as_ptr()) };
327        if rv == -1 {
328            Err(Error::KeyNotFound)
329        } else {
330            debug_assert!(rv >= 0);
331            Ok(rv as usize)
332        }
333    }
334
335    /// Returns the number of elements associated with a key in a map.
336    #[inline]
337    pub fn value_count(&self, key: &str) -> Result<usize> {
338        let key = Map::make_raw_key(key)?;
339        unsafe { self.value_count_raw_unchecked(&key) }
340    }
341
342    /// Retrieves a value type from a map.
343    ///
344    /// # Safety
345    /// The caller must ensure `key` is valid.
346    #[inline]
347    pub(crate) unsafe fn value_type_raw_unchecked(&self, key: &CStr) -> Result<ValueType> {
348        match unsafe { API::get_cached().prop_get_type(self, key.as_ptr()) } {
349            x if x == ffi::VSPropertyType_ptUnset as i32 => Err(Error::KeyNotFound),
350            x if x == ffi::VSPropertyType_ptInt as i32 => Ok(ValueType::Int),
351            x if x == ffi::VSPropertyType_ptFloat as i32 => Ok(ValueType::Float),
352            x if x == ffi::VSPropertyType_ptData as i32 => Ok(ValueType::Data),
353            x if x == ffi::VSPropertyType_ptVideoNode as i32 => Ok(ValueType::VideoNode),
354            x if x == ffi::VSPropertyType_ptAudioNode as i32 => Ok(ValueType::AudioNode),
355            x if x == ffi::VSPropertyType_ptVideoFrame as i32 => Ok(ValueType::VideoFrame),
356            x if x == ffi::VSPropertyType_ptAudioFrame as i32 => Ok(ValueType::AudioFrame),
357            x if x == ffi::VSPropertyType_ptFunction as i32 => Ok(ValueType::Function),
358            _ => unreachable!(),
359        }
360    }
361
362    /// Retrieves a value type from a map.
363    #[inline]
364    pub fn value_type(&self, key: &str) -> Result<ValueType> {
365        let key = Map::make_raw_key(key)?;
366        unsafe { self.value_type_raw_unchecked(&key) }
367    }
368
369    /// Deletes the given key.
370    ///
371    /// # Safety
372    /// The caller must ensure `key` is valid.
373    #[inline]
374    pub(crate) unsafe fn delete_key_raw_unchecked(&mut self, key: &CStr) -> Result<()> {
375        let result = unsafe { API::get_cached().prop_delete_key(self, key.as_ptr()) };
376        if result == 0 {
377            Err(Error::KeyNotFound)
378        } else {
379            debug_assert!(result == 1);
380            Ok(())
381        }
382    }
383
384    /// Deletes the given key.
385    #[inline]
386    pub fn delete_key(&mut self, key: &str) -> Result<()> {
387        let key = Map::make_raw_key(key)?;
388        unsafe { self.delete_key_raw_unchecked(&key) }
389    }
390
391    /// Retrieves a property value.
392    #[inline]
393    pub fn get<'map, T: Value<'map, 'elem>>(&'map self, key: &str) -> Result<T> {
394        T::get_from_map(self, key)
395    }
396
397    /// Retrieves an iterator over the map values.
398    #[inline]
399    pub fn get_iter<'map, T: Value<'map, 'elem>>(
400        &'map self,
401        key: &str,
402    ) -> Result<ValueIter<'map, 'elem, T>> {
403        T::get_iter_from_map(self, key)
404    }
405
406    /// Sets a property value.
407    #[inline]
408    pub fn set<'map, T: Value<'map, 'elem>>(&'map mut self, key: &str, x: &T) -> Result<()> {
409        T::store_in_map(self, key, x)
410    }
411
412    /// Appends a property value.
413    #[inline]
414    pub fn append<'map, T: Value<'map, 'elem>>(&'map mut self, key: &str, x: &T) -> Result<()> {
415        T::append_to_map(self, key, x)
416    }
417
418    /// Retrieves an integer from a map.
419    ///
420    /// This function retrieves the first value associated with the key.
421    #[inline]
422    pub fn get_int(&self, key: &str) -> Result<i64> {
423        let key = Map::make_raw_key(key)?;
424        unsafe { self.get_int_raw_unchecked(&key, 0) }
425    }
426
427    /// Retrieves integers from a map.
428    #[inline]
429    pub fn get_int_iter<'map>(&'map self, key: &str) -> Result<ValueIter<'map, 'elem, i64>> {
430        let key = Map::make_raw_key(key)?;
431        unsafe { ValueIter::<i64>::new(self, key) }
432    }
433
434    /// Retrieves an array of integers from a map.
435    ///
436    /// This is faster than iterating over a `get_int_iter()`.
437    #[inline]
438    pub fn get_int_array(&self, key: &str) -> Result<&[i64]> {
439        let key = Map::make_raw_key(key)?;
440        unsafe { self.get_int_array_raw_unchecked(&key) }
441    }
442
443    /// Retrieves a floating point number from a map.
444    ///
445    /// This function retrieves the first value associated with the key.
446    #[inline]
447    pub fn get_float(&self, key: &str) -> Result<f64> {
448        let key = Map::make_raw_key(key)?;
449        unsafe { self.get_float_raw_unchecked(&key, 0) }
450    }
451
452    /// Retrieves an array of floating point numbers from a map.
453    ///
454    /// This is faster than iterating over a `get_float_iter()`.
455    #[inline]
456    pub fn get_float_array(&self, key: &str) -> Result<&[f64]> {
457        let key = Map::make_raw_key(key)?;
458        unsafe { self.get_float_array_raw_unchecked(&key) }
459    }
460
461    /// Retrieves floating point numbers from a map.
462    #[inline]
463    pub fn get_float_iter<'map>(&'map self, key: &str) -> Result<ValueIter<'map, 'elem, f64>> {
464        let key = Map::make_raw_key(key)?;
465        unsafe { ValueIter::<f64>::new(self, key) }
466    }
467
468    /// Retrieves data from a map.
469    ///
470    /// This function retrieves the first value associated with the key.
471    #[inline]
472    pub fn get_data(&self, key: &str) -> Result<&[u8]> {
473        let key = Map::make_raw_key(key)?;
474        unsafe { self.get_data_raw_unchecked(&key, 0) }
475    }
476
477    /// Retrieves data from a map.
478    #[inline]
479    pub fn get_data_iter<'map>(
480        &'map self,
481        key: &str,
482    ) -> Result<ValueIter<'map, 'elem, &'map [u8]>> {
483        let key = Map::make_raw_key(key)?;
484        unsafe { ValueIter::<&[u8]>::new(self, key) }
485    }
486
487    /// Retrieves a node from a map.
488    ///
489    /// This function retrieves the first value associated with the key.
490    #[inline]
491    pub fn get_video_node(&self, key: &str) -> Result<Node<'elem>> {
492        let key = Map::make_raw_key(key)?;
493        unsafe { self.get_video_node_raw_unchecked(&key, 0) }
494    }
495
496    /// Retrieves nodes from a map.
497    #[inline]
498    pub fn get_video_node_iter<'map>(
499        &'map self,
500        key: &str,
501    ) -> Result<ValueIter<'map, 'elem, Node<'elem>>> {
502        let key = Map::make_raw_key(key)?;
503        unsafe { ValueIter::<Node>::new(self, key) }
504    }
505
506    /// Retrieves a frame from a map.
507    ///
508    /// This function retrieves the first value associated with the key.
509    #[inline]
510    pub fn get_video_frame(&self, key: &str) -> Result<FrameRef<'elem>> {
511        let key = Map::make_raw_key(key)?;
512        unsafe { self.get_video_frame_raw_unchecked(&key, 0) }
513    }
514
515    /// Retrieves frames from a map.
516    #[inline]
517    pub fn get_video_frame_iter<'map>(
518        &'map self,
519        key: &str,
520    ) -> Result<ValueIter<'map, 'elem, FrameRef<'elem>>> {
521        let key = Map::make_raw_key(key)?;
522        unsafe { ValueIter::<FrameRef>::new(self, key) }
523    }
524
525    /// Retrieves a function from a map.
526    ///
527    /// This function retrieves the first value associated with the key.
528    #[inline]
529    pub fn get_function(&self, key: &str) -> Result<Function<'elem>> {
530        let key = Map::make_raw_key(key)?;
531        unsafe { self.get_function_raw_unchecked(&key, 0) }
532    }
533
534    /// Retrieves functions from a map.
535    #[inline]
536    pub fn get_function_iter<'map>(
537        &'map self,
538        key: &str,
539    ) -> Result<ValueIter<'map, 'elem, Function<'elem>>> {
540        let key = Map::make_raw_key(key)?;
541        unsafe { ValueIter::<Function>::new(self, key) }
542    }
543
544    /// Retrieves an integer from a map.
545    ///
546    /// # Safety
547    /// The caller must ensure `key` is valid.
548    #[inline]
549    pub(crate) unsafe fn get_int_raw_unchecked(&self, key: &CStr, index: i32) -> Result<i64> {
550        let mut error = 0;
551        let value =
552            unsafe { API::get_cached().prop_get_int(self, key.as_ptr(), index, &mut error) };
553        handle_get_prop_error(error)?;
554
555        Ok(value)
556    }
557
558    /// Retrieves an array of integers from a map.
559    ///
560    /// # Safety
561    /// The caller must ensure `key` is valid.
562    #[inline]
563    pub(crate) unsafe fn get_int_array_raw_unchecked(&self, key: &CStr) -> Result<&[i64]> {
564        let mut error = 0;
565        let value = unsafe { API::get_cached().prop_get_int_array(self, key.as_ptr(), &mut error) };
566        handle_get_prop_error(error)?;
567
568        unsafe {
569            let length = self.value_count_raw_unchecked(key).unwrap();
570            Ok(slice::from_raw_parts(value, length))
571        }
572    }
573
574    /// Retrieves a floating point number from a map.
575    ///
576    /// # Safety
577    /// The caller must ensure `key` is valid.
578    #[inline]
579    pub(crate) unsafe fn get_float_raw_unchecked(&self, key: &CStr, index: i32) -> Result<f64> {
580        let mut error = 0;
581        let value =
582            unsafe { API::get_cached().prop_get_float(self, key.as_ptr(), index, &mut error) };
583        handle_get_prop_error(error)?;
584
585        Ok(value)
586    }
587
588    /// Retrieves an array of floating point numbers from a map.
589    ///
590    /// # Safety
591    /// The caller must ensure `key` is valid.
592    #[inline]
593    pub(crate) unsafe fn get_float_array_raw_unchecked(&self, key: &CStr) -> Result<&[f64]> {
594        let mut error = 0;
595        let value =
596            unsafe { API::get_cached().prop_get_float_array(self, key.as_ptr(), &mut error) };
597        handle_get_prop_error(error)?;
598
599        unsafe {
600            let length = self.value_count_raw_unchecked(key).unwrap();
601            Ok(slice::from_raw_parts(value, length))
602        }
603    }
604
605    /// Retrieves data from a map.
606    ///
607    /// # Safety
608    /// The caller must ensure `key` is valid.
609    #[inline]
610    pub(crate) unsafe fn get_data_raw_unchecked(&self, key: &CStr, index: i32) -> Result<&[u8]> {
611        let mut error = 0;
612        let value =
613            unsafe { API::get_cached().prop_get_data(self, key.as_ptr(), index, &mut error) };
614        handle_get_prop_error(error)?;
615
616        let mut error = 0;
617        let length =
618            unsafe { API::get_cached().prop_get_data_size(self, key.as_ptr(), index, &mut error) };
619        debug_assert!(error == 0);
620        debug_assert!(length >= 0);
621
622        unsafe { Ok(slice::from_raw_parts(value as *const u8, length as usize)) }
623    }
624
625    /// Retrieves a node from a map.
626    ///
627    /// # Safety
628    /// The caller must ensure `key` is valid.
629    #[inline]
630    pub(crate) unsafe fn get_video_node_raw_unchecked(
631        &self,
632        key: &CStr,
633        index: i32,
634    ) -> Result<Node<'elem>> {
635        let mut error = 0;
636        let value =
637            unsafe { API::get_cached().prop_get_node(self, key.as_ptr(), index, &mut error) };
638        handle_get_prop_error(error)?;
639
640        unsafe { Ok(Node::from_ptr(value)) }
641    }
642
643    /// Retrieves a frame from a map.
644    ///
645    /// # Safety
646    /// The caller must ensure `key` is valid.
647    #[inline]
648    pub(crate) unsafe fn get_video_frame_raw_unchecked(
649        &self,
650        key: &CStr,
651        index: i32,
652    ) -> Result<FrameRef<'elem>> {
653        let mut error = 0;
654        let value =
655            unsafe { API::get_cached().prop_get_frame(self, key.as_ptr(), index, &mut error) };
656        handle_get_prop_error(error)?;
657
658        unsafe { Ok(FrameRef::from_ptr(value)) }
659    }
660
661    /// Retrieves a function from a map.
662    ///
663    /// # Safety
664    /// The caller must ensure `key` is valid.
665    #[inline]
666    pub(crate) unsafe fn get_function_raw_unchecked(
667        &self,
668        key: &CStr,
669        index: i32,
670    ) -> Result<Function<'elem>> {
671        let mut error = 0;
672        let value =
673            unsafe { API::get_cached().prop_get_func(self, key.as_ptr(), index, &mut error) };
674        handle_get_prop_error(error)?;
675
676        unsafe { Ok(Function::from_ptr(value)) }
677    }
678
679    /// Appends an integer to a map.
680    #[inline]
681    pub fn append_int(&mut self, key: &str, x: i64) -> Result<()> {
682        let key = Map::make_raw_key(key)?;
683        unsafe { self.append_int_raw_unchecked(&key, x) }
684    }
685
686    /// Appends a floating point number to a map.
687    #[inline]
688    pub fn append_float(&mut self, key: &str, x: f64) -> Result<()> {
689        let key = Map::make_raw_key(key)?;
690        unsafe { self.append_float_raw_unchecked(&key, x) }
691    }
692
693    /// Appends data to a map.
694    #[inline]
695    pub fn append_data(&mut self, key: &str, x: &[u8]) -> Result<()> {
696        let key = Map::make_raw_key(key)?;
697        unsafe { self.append_data_raw_unchecked(&key, x) }
698    }
699
700    /// Appends a node to a map.
701    #[inline]
702    pub fn append_node(&mut self, key: &str, x: &Node<'elem>) -> Result<()> {
703        let key = Map::make_raw_key(key)?;
704        unsafe { self.append_node_raw_unchecked(&key, x) }
705    }
706
707    /// Appends a frame to a map.
708    #[inline]
709    pub fn append_frame(&mut self, key: &str, x: &Frame<'elem>) -> Result<()> {
710        let key = Map::make_raw_key(key)?;
711        unsafe { self.append_frame_raw_unchecked(&key, x) }
712    }
713
714    /// Appends a function to a map.
715    #[inline]
716    pub fn append_function(&mut self, key: &str, x: &Function<'elem>) -> Result<()> {
717        let key = Map::make_raw_key(key)?;
718        unsafe { self.append_function_raw_unchecked(&key, x) }
719    }
720
721    /// Appends an integer to a map.
722    ///
723    /// # Safety
724    /// The caller must ensure `key` is valid.
725    #[inline]
726    pub(crate) unsafe fn append_int_raw_unchecked(&mut self, key: &CStr, x: i64) -> Result<()> {
727        let error = unsafe {
728            API::get_cached().prop_set_int(self, key.as_ptr(), x, ffi::VSMapAppendMode_maAppend)
729        };
730
731        handle_append_prop_error(error)
732    }
733
734    /// Appends a floating point number to a map.
735    ///
736    /// # Safety
737    /// The caller must ensure `key` is valid.
738    #[inline]
739    pub(crate) unsafe fn append_float_raw_unchecked(&mut self, key: &CStr, x: f64) -> Result<()> {
740        let error = unsafe {
741            API::get_cached().prop_set_float(self, key.as_ptr(), x, ffi::VSMapAppendMode_maAppend)
742        };
743
744        handle_append_prop_error(error)
745    }
746
747    /// Appends data to a map.
748    ///
749    /// # Safety
750    /// The caller must ensure `key` is valid.
751    #[inline]
752    pub(crate) unsafe fn append_data_raw_unchecked(&mut self, key: &CStr, x: &[u8]) -> Result<()> {
753        let error = unsafe {
754            API::get_cached().prop_set_data(self, key.as_ptr(), x, ffi::VSMapAppendMode_maAppend)
755        };
756
757        handle_append_prop_error(error)
758    }
759
760    /// Appends a node to a map.
761    ///
762    /// # Safety
763    /// The caller must ensure `key` is valid.
764    #[inline]
765    pub(crate) unsafe fn append_node_raw_unchecked(
766        &mut self,
767        key: &CStr,
768        x: &Node<'elem>,
769    ) -> Result<()> {
770        let error = unsafe {
771            API::get_cached().prop_set_node(
772                self,
773                key.as_ptr(),
774                x.ptr(),
775                ffi::VSMapAppendMode_maAppend,
776            )
777        };
778
779        handle_append_prop_error(error)
780    }
781
782    /// Appends a frame to a map.
783    ///
784    /// # Safety
785    /// The caller must ensure `key` is valid.
786    #[inline]
787    pub(crate) unsafe fn append_frame_raw_unchecked(
788        &mut self,
789        key: &CStr,
790        x: &Frame<'elem>,
791    ) -> Result<()> {
792        let error = unsafe {
793            API::get_cached().prop_set_frame(
794                self,
795                key.as_ptr(),
796                x.deref(),
797                ffi::VSMapAppendMode_maAppend,
798            )
799        };
800
801        handle_append_prop_error(error)
802    }
803
804    /// Appends a function to a map.
805    ///
806    /// # Safety
807    /// The caller must ensure `key` is valid.
808    #[inline]
809    pub(crate) unsafe fn append_function_raw_unchecked(
810        &mut self,
811        key: &CStr,
812        x: &Function<'elem>,
813    ) -> Result<()> {
814        let error = unsafe {
815            API::get_cached().prop_set_func(
816                self,
817                key.as_ptr(),
818                x.ptr(),
819                ffi::VSMapAppendMode_maAppend,
820            )
821        };
822
823        handle_append_prop_error(error)
824    }
825
826    /// Sets a property value to an integer.
827    #[inline]
828    pub fn set_int(&mut self, key: &str, x: i64) -> Result<()> {
829        let key = Map::make_raw_key(key)?;
830        unsafe {
831            self.set_int_raw_unchecked(&key, x);
832        }
833        Ok(())
834    }
835
836    /// Sets a property value to an integer array.
837    ///
838    /// This is faster than calling `append_int()` in a loop.
839    #[inline]
840    pub fn set_int_array(&mut self, key: &str, x: &[i64]) -> Result<()> {
841        let key = Map::make_raw_key(key)?;
842        unsafe {
843            self.set_int_array_raw_unchecked(&key, x);
844        }
845        Ok(())
846    }
847
848    /// Sets a property value to a floating point number.
849    #[inline]
850    pub fn set_float(&mut self, key: &str, x: f64) -> Result<()> {
851        let key = Map::make_raw_key(key)?;
852        unsafe {
853            self.set_float_raw_unchecked(&key, x);
854        }
855        Ok(())
856    }
857
858    /// Sets a property value to a floating point number array.
859    ///
860    /// This is faster than calling `append_float()` in a loop.
861    #[inline]
862    pub fn set_float_array(&mut self, key: &str, x: &[f64]) -> Result<()> {
863        let key = Map::make_raw_key(key)?;
864        unsafe {
865            self.set_float_array_raw_unchecked(&key, x);
866        }
867        Ok(())
868    }
869
870    /// Sets a property value to data.
871    #[inline]
872    pub fn set_data(&mut self, key: &str, x: &[u8]) -> Result<()> {
873        let key = Map::make_raw_key(key)?;
874        unsafe {
875            self.set_data_raw_unchecked(&key, x);
876        }
877        Ok(())
878    }
879
880    /// Sets a property value to a node.
881    #[inline]
882    pub fn set_node(&mut self, key: &str, x: &Node<'elem>) -> Result<()> {
883        let key = Map::make_raw_key(key)?;
884        unsafe {
885            self.set_node_raw_unchecked(&key, x);
886        }
887        Ok(())
888    }
889
890    /// Sets a property value to a frame.
891    #[inline]
892    pub fn set_frame(&mut self, key: &str, x: &Frame<'elem>) -> Result<()> {
893        let key = Map::make_raw_key(key)?;
894        unsafe {
895            self.set_frame_raw_unchecked(&key, x);
896        }
897        Ok(())
898    }
899
900    /// Sets a property value to a function.
901    #[inline]
902    pub fn set_function(&mut self, key: &str, x: &Function<'elem>) -> Result<()> {
903        let key = Map::make_raw_key(key)?;
904        unsafe {
905            self.set_function_raw_unchecked(&key, x);
906        }
907        Ok(())
908    }
909
910    /// Sets a property value to an integer.
911    ///
912    /// # Safety
913    /// The caller must ensure `key` is valid.
914    #[inline]
915    pub(crate) unsafe fn set_int_raw_unchecked(&mut self, key: &CStr, x: i64) {
916        let error = unsafe {
917            API::get_cached().prop_set_int(self, key.as_ptr(), x, ffi::VSMapAppendMode_maReplace)
918        };
919
920        debug_assert!(error == 0);
921    }
922
923    /// Sets a property value to an integer array.
924    ///
925    /// # Safety
926    /// The caller must ensure `key` is valid.
927    ///
928    /// # Panics
929    /// Panics if `x.len()` can't fit in an `i32`.
930    #[inline]
931    pub(crate) unsafe fn set_int_array_raw_unchecked(&mut self, key: &CStr, x: &[i64]) {
932        let error = unsafe { API::get_cached().prop_set_int_array(self, key.as_ptr(), x) };
933
934        debug_assert!(error == 0);
935    }
936
937    /// Sets a property value to a floating point number.
938    ///
939    /// # Safety
940    /// The caller must ensure `key` is valid.
941    #[inline]
942    pub(crate) unsafe fn set_float_raw_unchecked(&mut self, key: &CStr, x: f64) {
943        let error = unsafe {
944            API::get_cached().prop_set_float(self, key.as_ptr(), x, ffi::VSMapAppendMode_maReplace)
945        };
946
947        debug_assert!(error == 0);
948    }
949
950    /// Sets a property value to a floating point number array.
951    ///
952    /// # Safety
953    /// The caller must ensure `key` is valid.
954    ///
955    /// # Panics
956    /// Panics if `x.len()` can't fit in an `i32`.
957    #[inline]
958    pub(crate) unsafe fn set_float_array_raw_unchecked(&mut self, key: &CStr, x: &[f64]) {
959        let error = unsafe { API::get_cached().prop_set_float_array(self, key.as_ptr(), x) };
960
961        debug_assert!(error == 0);
962    }
963
964    /// Sets a property value to data.
965    ///
966    /// # Safety
967    /// The caller must ensure `key` is valid.
968    #[inline]
969    pub(crate) unsafe fn set_data_raw_unchecked(&mut self, key: &CStr, x: &[u8]) {
970        let error = unsafe {
971            API::get_cached().prop_set_data(self, key.as_ptr(), x, ffi::VSMapAppendMode_maReplace)
972        };
973
974        debug_assert!(error == 0);
975    }
976
977    /// Sets a property value to a node.
978    ///
979    /// # Safety
980    /// The caller must ensure `key` is valid.
981    #[inline]
982    pub(crate) unsafe fn set_node_raw_unchecked(&mut self, key: &CStr, x: &Node<'elem>) {
983        let error = unsafe {
984            API::get_cached().prop_set_node(
985                self,
986                key.as_ptr(),
987                x.ptr(),
988                ffi::VSMapAppendMode_maReplace,
989            )
990        };
991
992        debug_assert!(error == 0);
993    }
994
995    /// Sets a property value to a frame.
996    ///
997    /// # Safety
998    /// The caller must ensure `key` is valid.
999    #[inline]
1000    pub(crate) unsafe fn set_frame_raw_unchecked(&mut self, key: &CStr, x: &Frame<'elem>) {
1001        let error = unsafe {
1002            API::get_cached().prop_set_frame(
1003                self,
1004                key.as_ptr(),
1005                x.deref(),
1006                ffi::VSMapAppendMode_maReplace,
1007            )
1008        };
1009
1010        debug_assert!(error == 0);
1011    }
1012
1013    /// Sets a property value to a function.
1014    ///
1015    /// # Safety
1016    /// The caller must ensure `key` is valid.
1017    #[inline]
1018    pub(crate) unsafe fn set_function_raw_unchecked(&mut self, key: &CStr, x: &Function<'elem>) {
1019        let error = unsafe {
1020            API::get_cached().prop_set_func(
1021                self,
1022                key.as_ptr(),
1023                x.ptr(),
1024                ffi::VSMapAppendMode_maReplace,
1025            )
1026        };
1027
1028        debug_assert!(error == 0);
1029    }
1030}