use rosc::{OscBundle, OscMessage, OscPacket, OscType};
pub trait OscMessageExt {
fn new<T>(addr: impl ToString, args: T) -> Self
where
T: IntoOscArgs;
fn starts_with(&self, prefix: &str) -> bool;
fn as_tuple(&self) -> (&str, &[OscType]);
}
impl OscMessageExt for OscMessage {
fn new<T>(addr: impl ToString, args: T) -> Self
where
T: IntoOscArgs,
{
let args = args.into_osc_args();
let addr = addr.to_string();
OscMessage { addr, args }
}
fn starts_with(&self, prefix: &str) -> bool {
self.addr.starts_with(prefix)
}
fn as_tuple(&self) -> (&str, &[OscType]) {
(self.addr.as_str(), &self.args[..])
}
}
pub trait OscPacketExt {
fn message(&self) -> Option<&OscMessage>;
fn into_message(self) -> Option<OscMessage>;
}
impl OscPacketExt for OscPacket {
fn message(&self) -> Option<&OscMessage> {
match self {
OscPacket::Message(message) => Some(message),
_ => None,
}
}
fn into_message(self) -> Option<OscMessage> {
match self {
OscPacket::Message(message) => Some(message),
_ => None,
}
}
}
pub trait IntoOscArgs {
fn into_osc_args(self) -> Vec<OscType>;
}
impl<T> IntoOscArgs for Vec<T>
where
T: Into<OscType>,
{
fn into_osc_args(self) -> Vec<OscType> {
let args: Vec<OscType> = self.into_iter().map(|a| a.into()).collect();
args
}
}
impl<T1> IntoOscArgs for (T1,)
where
T1: Into<OscType>,
{
fn into_osc_args(self) -> Vec<OscType> {
vec![self.0.into()]
}
}
impl<T1, T2> IntoOscArgs for (T1, T2)
where
T1: Into<OscType>,
T2: Into<OscType>,
{
fn into_osc_args(self) -> Vec<OscType> {
vec![self.0.into(), self.1.into()]
}
}
impl<T1, T2, T3> IntoOscArgs for (T1, T2, T3)
where
T1: Into<OscType>,
T2: Into<OscType>,
T3: Into<OscType>,
{
fn into_osc_args(self) -> Vec<OscType> {
vec![self.0.into(), self.1.into(), self.2.into()]
}
}
impl IntoOscArgs for OscType {
fn into_osc_args(self) -> Vec<OscType> {
vec![self]
}
}
pub trait IntoOscPacket {
fn into_osc_packet(self) -> OscPacket;
}
impl IntoOscPacket for OscMessage {
fn into_osc_packet(self) -> OscPacket {
OscPacket::Message(self)
}
}
impl IntoOscPacket for OscBundle {
fn into_osc_packet(self) -> OscPacket {
OscPacket::Bundle(self)
}
}
impl IntoOscPacket for OscPacket {
fn into_osc_packet(self) -> OscPacket {
self
}
}
impl<T> IntoOscPacket for T
where
T: IntoOscMessage,
{
fn into_osc_packet(self) -> OscPacket {
OscPacket::Message(self.into_osc_message())
}
}
pub trait IntoOscMessage {
fn into_osc_message(self) -> OscMessage;
}
impl<S, A> IntoOscMessage for (S, A)
where
S: ToString,
A: IntoOscArgs,
{
fn into_osc_message(self) -> OscMessage {
OscMessage::new(self.0, self.1)
}
}