libspa/node/
command.rs

1// Copyright The pipewire-rs Contributors.
2// SPDX-License-Identifier: MIT
3
4use crate::{constants::ID_INVALID, pod::command::CommandError, utils::SpaTypes};
5
6#[derive(Copy, Clone, PartialEq, Eq)]
7pub struct NodeCommandId(spa_sys::spa_node_command);
8
9impl NodeCommandId {
10    pub const SUSPEND: Self = Self(spa_sys::SPA_NODE_COMMAND_Suspend);
11    pub const PAUSE: Self = Self(spa_sys::SPA_NODE_COMMAND_Pause);
12    pub const START: Self = Self(spa_sys::SPA_NODE_COMMAND_Start);
13    pub const ENABLE: Self = Self(spa_sys::SPA_NODE_COMMAND_Enable);
14    pub const DISABLE: Self = Self(spa_sys::SPA_NODE_COMMAND_Disable);
15    pub const FLUSH: Self = Self(spa_sys::SPA_NODE_COMMAND_Flush);
16    pub const DRAIN: Self = Self(spa_sys::SPA_NODE_COMMAND_Drain);
17    pub const MARKER: Self = Self(spa_sys::SPA_NODE_COMMAND_Marker);
18    pub const PARAM_BEGIN: Self = Self(spa_sys::SPA_NODE_COMMAND_ParamBegin);
19    pub const PARAM_END: Self = Self(spa_sys::SPA_NODE_COMMAND_ParamEnd);
20    pub const REQUEST_PROCESS: Self = Self(spa_sys::SPA_NODE_COMMAND_RequestProcess);
21
22    pub fn as_raw(&self) -> spa_sys::spa_node_command {
23        self.0
24    }
25
26    pub fn from_raw(raw: spa_sys::spa_node_command) -> Self {
27        Self(raw)
28    }
29}
30
31impl std::fmt::Debug for NodeCommandId {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        let debug_name = unsafe {
34            let c_name =
35                spa_sys::spa_debug_type_find_name(spa_sys::spa_type_node_command_id, self.as_raw());
36
37            assert!(
38                !c_name.is_null(),
39                "unknown node command id {}",
40                self.as_raw()
41            );
42
43            std::ffi::CStr::from_ptr(c_name)
44        };
45
46        debug_name.fmt(f)
47    }
48}
49
50/// Newtype wrapper around [`crate::pod::command::Command`] for node commands.
51pub struct NodeCommand(crate::pod::command::Command);
52
53impl NodeCommand {
54    pub fn new(id: NodeCommandId) -> Self {
55        let raw = unsafe { spa_sys::spa_node_command_init(id.as_raw()) };
56        Self(crate::pod::command::Command::from_raw(raw))
57    }
58
59    pub fn id(&self) -> NodeCommandId {
60        let id = unsafe { spa_sys::spa_node_command_id(self.as_raw_ptr()) };
61
62        assert_ne!(id, ID_INVALID, "node command has unexpected type");
63
64        NodeCommandId::from_raw(id)
65    }
66
67    /// # Errors
68    ///
69    /// This function will return an error if `pod` is not of type [`SpaTypes::CommandNode`][crate::utils::SpaTypes]
70    pub fn from_pod(pod: crate::pod::command::Command) -> Result<Self, CommandError> {
71        if pod.id(SpaTypes::CommandNode).is_err() {
72            Err(CommandError::WrongCommandType)
73        } else {
74            Ok(Self(pod))
75        }
76    }
77}
78
79impl From<NodeCommandId> for NodeCommand {
80    fn from(value: NodeCommandId) -> Self {
81        Self::new(value)
82    }
83}
84
85impl std::ops::Deref for NodeCommand {
86    type Target = crate::pod::command::Command;
87
88    fn deref(&self) -> &Self::Target {
89        &self.0
90    }
91}