libmpv_client/types/
node_array.rs

1use std::ffi::{c_int, c_void};
2use std::marker::PhantomData;
3use std::mem::MaybeUninit;
4use std::ptr::null_mut;
5use libmpv_client_sys::{mpv_node, mpv_node_list};
6use crate::*;
7use crate::node::MpvNode;
8use crate::types::traits::{MpvFormat, MpvRecv, MpvRecvInternal, MpvRepr, MpvSend, MpvSendInternal, ToMpvRepr};
9
10/// A [`Vec<Node>`], used only within a [`Node`], and only in specific situations.
11pub type NodeArray = Vec<Node>;
12
13#[derive(Debug)]
14pub(crate) struct MpvNodeArray<'a> {
15    _original: PhantomData<&'a NodeArray>,
16
17    _owned_reprs: Vec<MpvNode<'a>>,
18    _flat_reprs: Vec<mpv_node>,
19
20    node_list: Box<mpv_node_list>,
21}
22
23impl MpvRepr for MpvNodeArray<'_> {
24    type Repr = mpv_node_list;
25
26    fn ptr(&self) -> *const Self::Repr {
27        &raw const *self.node_list
28    }
29}
30
31impl MpvFormat for NodeArray {
32    const MPV_FORMAT: Format = Format::NODE_ARRAY;
33}
34
35impl From<NodeArray> for Node {
36    fn from(value: NodeArray) -> Self {
37        Node::Array(value)
38    }
39}
40
41impl From<&NodeArray> for Node {
42    fn from(value: &NodeArray) -> Self {
43        Node::Array(value.clone())
44    }
45}
46
47impl MpvRecv for NodeArray {}
48impl MpvRecvInternal for NodeArray {
49    unsafe fn from_ptr(ptr: *const c_void) -> Result<Self> {
50        check_null!(ptr);
51        let node_list = unsafe { *(ptr as *const mpv_node_list) };
52
53        check_null!(node_list.values);
54        let mut values = Vec::with_capacity(node_list.num as usize);
55
56        let node_values = unsafe { std::slice::from_raw_parts(node_list.values, node_list.num as usize) };
57        for node_value in node_values {
58            values.push(unsafe { Node::from_node_ptr(node_value)? });
59        }
60
61        Ok(values)
62    }
63
64    unsafe fn from_mpv<F: Fn(*mut c_void) -> Result<i32>>(fun: F) -> Result<Self> {
65        let mut node_list: MaybeUninit<mpv_node_list> = MaybeUninit::uninit();
66
67        fun(node_list.as_mut_ptr() as *mut c_void).map(|_| {
68            unsafe { Self::from_ptr(node_list.as_ptr() as *const c_void) }
69        })?
70    }
71}
72
73impl MpvSend for NodeArray {}
74impl MpvSendInternal for NodeArray {
75    fn to_mpv<F: Fn(*mut c_void) -> Result<i32>>(&self, fun: F) -> Result<i32> {
76        let repr = self.to_mpv_repr();
77
78        fun(repr.ptr() as *mut c_void)
79    }
80}
81
82impl ToMpvRepr for NodeArray {
83    type ReprWrap<'a> = MpvNodeArray<'a>;
84
85    fn to_mpv_repr(&self) -> Self::ReprWrap<'_> {
86        let mut repr = MpvNodeArray {
87            _original: PhantomData,
88            _owned_reprs: Vec::with_capacity(self.len()),
89            _flat_reprs: Vec::with_capacity(self.len()),
90            node_list: Box::new(mpv_node_list {
91                num: self.len() as c_int,
92                values: null_mut(),
93                keys: null_mut(),
94            }),
95        };
96
97        for node in self {
98            let node_repr = node.to_mpv_repr();
99            repr._flat_reprs.push(*node_repr.node);
100            repr._owned_reprs.push(node_repr);
101        }
102
103        repr.node_list.values = repr._flat_reprs.as_ptr() as *mut _;
104
105        repr
106    }
107}