libmpv_client/types/
node.rs1#![allow(non_upper_case_globals)]
2
3use std::collections::HashMap;
4use std::ffi::{c_void, CStr, CString, c_char};
5use std::fmt::Debug;
6use std::marker::PhantomData;
7use std::mem::MaybeUninit;
8use libmpv_client_sys::{mpv_byte_array, mpv_format_MPV_FORMAT_BYTE_ARRAY, mpv_format_MPV_FORMAT_DOUBLE, mpv_format_MPV_FORMAT_FLAG, mpv_format_MPV_FORMAT_INT64, mpv_format_MPV_FORMAT_NODE_ARRAY, mpv_format_MPV_FORMAT_NODE_MAP, mpv_format_MPV_FORMAT_NONE, mpv_format_MPV_FORMAT_STRING, mpv_node, mpv_node__bindgen_ty_1, mpv_node_list};
9use crate::*;
10use crate::byte_array::MpvByteArray;
11use crate::node_array::MpvNodeArray;
12use crate::node_map::MpvNodeMap;
13use crate::types::traits::{MpvFormat, MpvRecv, MpvRecvInternal, MpvRepr, MpvSend, MpvSendInternal, ToMpvRepr};
14
15#[derive(Debug, Clone, PartialEq)]
17pub enum Node {
18 None,
20 String(String),
22 Flag(bool),
24 Int64(i64),
26 Double(f64),
28 Array(NodeArray),
30 Map(NodeMap),
32 ByteArray(ByteArray),
34}
35
36#[derive(Debug)]
37pub(crate) struct MpvNode<'a> {
38 _original: PhantomData<&'a Node>,
39
40 _owned_cstring: Option<CString>,
41 _array_repr: Option<MpvNodeArray<'a>>,
42 _map_repr: Option<MpvNodeMap<'a>>,
43 _bytes_repr: Option<MpvByteArray<'a>>,
44
45 pub(crate) node: Box<mpv_node>,
46}
47
48impl MpvRepr for MpvNode<'_> {
49 type Repr = mpv_node;
50
51 fn ptr(&self) -> *const Self::Repr {
52 &raw const *self.node
53 }
54}
55
56impl MpvFormat for Node {
57 const MPV_FORMAT: Format = Format::NODE;
58}
59
60impl MpvRecv for Node {}
61impl MpvRecvInternal for Node {
62 unsafe fn from_ptr(ptr: *const c_void) -> Result<Self> {
63 unsafe { Self::from_node_ptr(ptr as *const mpv_node) }
64 }
65
66 unsafe fn from_mpv<F: Fn(*mut c_void) -> Result<i32>>(fun: F) -> Result<Self> {
67 let mut node: MaybeUninit<mpv_node> = MaybeUninit::uninit();
68
69 fun(node.as_mut_ptr() as *mut c_void).map(|_| {
70 let ret = unsafe { Self::from_node_ptr(node.as_ptr()) };
71 unsafe { mpv_free_node_contents(node.as_mut_ptr()) }
72 ret
73 })?
74 }
75}
76
77impl MpvSend for Node {}
78impl MpvSendInternal for Node {
79 fn to_mpv<F: Fn(*mut c_void) -> Result<i32>>(&self, fun: F) -> Result<i32> {
80 let repr = self.to_mpv_repr();
81
82 fun(repr.ptr() as *mut c_void)
83 }
84}
85
86impl ToMpvRepr for Node {
87 type ReprWrap<'a> = MpvNode<'a>;
88
89 fn to_mpv_repr(&self) -> Self::ReprWrap<'_> {
90 let mut repr = MpvNode {
91 _original: PhantomData,
92 _owned_cstring: None,
93 _array_repr: None,
94 _map_repr: None,
95 _bytes_repr: None,
96 node: Box::new(mpv_node { u: mpv_node__bindgen_ty_1 { int64: 0 }, format: 0 }),
97 };
98
99 match self {
100 Node::None => {
101 repr.node.u = mpv_node__bindgen_ty_1 { flag: 0 };
102 repr.node.format = mpv_format_MPV_FORMAT_NONE;
103 },
104 Node::String(x) => {
105 repr._owned_cstring = Some(CString::new(x.as_bytes()).unwrap_or_default());
107 let cstring_ptr = repr._owned_cstring.as_ref().unwrap().as_ptr(); repr.node.u = mpv_node__bindgen_ty_1 { string: cstring_ptr as *mut c_char };
110 repr.node.format = mpv_format_MPV_FORMAT_STRING;
111 }
112 Node::Flag(x) => {
113 repr.node.u = mpv_node__bindgen_ty_1 { flag: if *x { 1 } else { 0 } };
114 repr.node.format = mpv_format_MPV_FORMAT_FLAG;
115 }
116 Node::Int64(x) => {
117 repr.node.u = mpv_node__bindgen_ty_1 { int64: *x };
118 repr.node.format = mpv_format_MPV_FORMAT_INT64;
119 }
120 Node::Double(x) => {
121 repr.node.u = mpv_node__bindgen_ty_1 { double_: *x };
122 repr.node.format = mpv_format_MPV_FORMAT_DOUBLE;
123 }
124 Node::Array(x) => {
125 repr._array_repr = Some(x.to_mpv_repr());
126 let mpv_ptr = repr._array_repr.as_ref().unwrap().ptr(); repr.node.u = mpv_node__bindgen_ty_1 { list: mpv_ptr as *mut mpv_node_list };
129 repr.node.format = mpv_format_MPV_FORMAT_NODE_ARRAY;
130 }
131 Node::Map(x) => {
132 repr._map_repr = Some(x.to_mpv_repr());
133 let mpv_ptr = repr._map_repr.as_ref().unwrap().ptr(); repr.node.u = mpv_node__bindgen_ty_1 { list: mpv_ptr as *mut mpv_node_list };
136 repr.node.format = mpv_format_MPV_FORMAT_NODE_MAP;
137 }
138 Node::ByteArray(x) => {
139 repr._bytes_repr = Some(x.to_mpv_repr());
140 let mpv_ptr = repr._bytes_repr.as_ref().unwrap().ptr(); repr.node.u = mpv_node__bindgen_ty_1 { ba: mpv_ptr as *mut mpv_byte_array };
143 repr.node.format = mpv_format_MPV_FORMAT_BYTE_ARRAY;
144 }
145 };
146
147 repr
148 }
149}
150
151impl Node {
152 pub(crate) unsafe fn from_node_ptr(ptr: *const mpv_node) -> Result<Self> {
153 check_null!(ptr);
154 let node = unsafe { *ptr };
155
156 match node.format {
157 mpv_format_MPV_FORMAT_NONE => Ok(Node::None),
158 mpv_format_MPV_FORMAT_STRING => Ok(Node::String(unsafe { CStr::from_ptr(node.u.string) }.to_str()?.to_string())),
159 mpv_format_MPV_FORMAT_FLAG => Ok(Node::Flag(unsafe { node.u.flag } != 0)),
160 mpv_format_MPV_FORMAT_INT64 => Ok(Node::Int64(unsafe { node.u.int64 })),
161 mpv_format_MPV_FORMAT_DOUBLE => Ok(Node::Double(unsafe { node.u.double_ })),
162 mpv_format_MPV_FORMAT_NODE_ARRAY => Ok(Node::Array(unsafe { NodeArray::from_ptr(node.u.list as *const c_void)? })),
163 mpv_format_MPV_FORMAT_NODE_MAP => Ok(Node::Map(unsafe { NodeMap::from_ptr(node.u.list as *const c_void)? })),
164 mpv_format_MPV_FORMAT_BYTE_ARRAY => Ok(Node::ByteArray(unsafe { ByteArray::from_ptr(node.u.ba as *const c_void)? })),
165 _ => unimplemented!()
166 }
167 }
168}
169
170impl From<&[(&str, Node)]> for Node {
171 fn from(slice: &[(&str, Node)]) -> Self {
175 let map: HashMap<String, Node> = slice.iter()
176 .map(|(k, v)| (k.to_string(), v.clone()))
177 .collect();
178 Node::Map(map)
179 }
180}
181
182impl From<&[Node]> for Node {
183 fn from(slice: &[Node]) -> Self {
187 Node::Array(slice.to_vec())
188 }
189}