#[cfg(feature = "v0_4_11")]
use crate::pw::LinkState;
use crate::{
core::Core,
prelude::*,
pw::{self, Direction, Link, Node, Port, Properties},
};
impl Link {
#[doc(alias("wp_link_new_from_factory"))]
pub fn new<O: LinkTarget + Debug, I: LinkTarget + Debug>(
core: &Core,
output: &O,
input: &I,
props: &Properties,
) -> Result<Self, Error> {
let props = Properties::new_clone(props);
output.write_props(&props, Direction::Output)?;
input.write_props(&props, Direction::Input)?;
Self::from_factory(core, "link-factory", Some(props))
.ok_or_else(|| Error::new(LibraryErrorEnum::OperationFailed, "factory did not produce a link???"))
}
pub fn error_is_exists(e: &Error) -> bool {
e.message().ends_with(": File exists") }
#[cfg(feature = "v0_4_11")]
#[cfg_attr(docsrs, doc(cfg(feature = "v0_4_11")))]
#[doc(alias = "wp_link_get_state")]
#[doc(alias = "get_state")]
pub fn state(&self) -> LinkState {
unsafe { from_glib(ffi::wp_link_get_state(self.to_glib_none().0, ptr::null_mut())) }
}
#[cfg(feature = "v0_4_11")]
#[cfg_attr(docsrs, doc(cfg(feature = "v0_4_11")))]
#[doc(alias = "wp_link_get_state")]
#[doc(alias = "get_state")]
pub fn state_result(&self) -> Result<LinkState, Error> {
unsafe {
let mut error = ptr::null();
match from_glib(ffi::wp_link_get_state(self.to_glib_none().0, &mut error)) {
LinkState::Error => {
let msg: Option<&glib::GStr> = from_glib_none(error);
Err(Error::new(
LibraryErrorEnum::OperationFailed,
msg.map(|s| s.as_str()).unwrap_or("unspecified link state error"),
))
},
state => Ok(state),
}
}
}
}
pub trait LinkTarget {
fn write_props(&self, props: &Properties, dir: Direction) -> Result<(), Error>;
}
impl LinkTarget for Node {
fn write_props(&self, props: &Properties, dir: Direction) -> Result<(), Error> {
match dir {
Direction::Output => props.insert(pw::PW_KEY_LINK_OUTPUT_NODE, self.bound_id()),
Direction::Input => props.insert(pw::PW_KEY_LINK_INPUT_NODE, self.bound_id()),
_ => unreachable!(),
}
Ok(())
}
}
impl LinkTarget for Port {
fn write_props(&self, props: &Properties, dir: Direction) -> Result<(), Error> {
let node_id = self.node_id()?;
match dir {
Direction::Output => {
props.insert(pw::PW_KEY_LINK_OUTPUT_PORT, self.port_index()?);
props.insert(pw::PW_KEY_LINK_OUTPUT_NODE, node_id);
},
Direction::Input => {
props.insert(pw::PW_KEY_LINK_INPUT_PORT, self.port_index()?);
props.insert(pw::PW_KEY_LINK_INPUT_NODE, node_id);
},
_ => unreachable!(),
}
Ok(())
}
}
#[cfg(not(feature = "v0_4_11"))]
impl StaticType for pw::LinkFeatures {
fn static_type() -> Type {
pw::ProxyFeatures::static_type()
}
}
#[cfg(feature = "v0_4_11")]
impl<E> From<Result<LinkState, E>> for LinkState {
fn from(res: Result<LinkState, E>) -> Self {
match res {
Ok(state) => state,
Err(_) => LinkState::Error,
}
}
}
impl Direction {
pub fn name(&self) -> &'static str {
match self {
Direction::Input => "input",
Direction::Output => "output",
Direction::__Unknown(direction) => panic!("unknown WP_DIRECTION {direction}"),
}
}
}
impl fmt::Display for Direction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.name())
}
}
impl FromStr for Direction {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"input" => Direction::Input,
"output" => Direction::Output,
_ =>
return Err(Error::new(
LibraryErrorEnum::InvalidArgument,
&format!("unknown direction {s}"),
)),
})
}
}