libmpv_client/types/
node_array.rs1use 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
10pub 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}