1use rosc::{OscBundle, OscMessage, OscPacket, OscType};
2
3pub trait OscMessageExt {
5 fn new<T>(addr: impl ToString, args: T) -> Self
9 where
10 T: IntoOscArgs;
11
12 fn starts_with(&self, prefix: &str) -> bool;
16
17 fn as_tuple(&self) -> (&str, &[OscType]);
35}
36
37impl OscMessageExt for OscMessage {
38 fn new<T>(addr: impl ToString, args: T) -> Self
39 where
40 T: IntoOscArgs,
41 {
42 let args = args.into_osc_args();
43 let addr = addr.to_string();
44 OscMessage { addr, args }
45 }
46
47 fn starts_with(&self, prefix: &str) -> bool {
48 self.addr.starts_with(prefix)
49 }
50
51 fn as_tuple(&self) -> (&str, &[OscType]) {
52 (self.addr.as_str(), &self.args[..])
53 }
54}
55
56pub trait OscPacketExt {
58 fn message(&self) -> Option<&OscMessage>;
62
63 fn into_message(self) -> Option<OscMessage>;
67}
68
69impl OscPacketExt for OscPacket {
70 fn message(&self) -> Option<&OscMessage> {
71 match self {
72 OscPacket::Message(message) => Some(message),
73 _ => None,
74 }
75 }
76 fn into_message(self) -> Option<OscMessage> {
77 match self {
78 OscPacket::Message(message) => Some(message),
79 _ => None,
80 }
81 }
82}
83
84pub trait IntoOscArgs {
86 fn into_osc_args(self) -> Vec<OscType>;
88}
89
90impl<T> IntoOscArgs for Vec<T>
91where
92 T: Into<OscType>,
93{
94 fn into_osc_args(self) -> Vec<OscType> {
95 let args: Vec<OscType> = self.into_iter().map(|a| a.into()).collect();
96 args
97 }
98}
99
100impl<T1> IntoOscArgs for (T1,)
113where
114 T1: Into<OscType>,
115{
116 fn into_osc_args(self) -> Vec<OscType> {
117 vec![self.0.into()]
118 }
119}
120
121impl<T1, T2> IntoOscArgs for (T1, T2)
122where
123 T1: Into<OscType>,
124 T2: Into<OscType>,
125{
126 fn into_osc_args(self) -> Vec<OscType> {
127 vec![self.0.into(), self.1.into()]
128 }
129}
130
131impl<T1, T2, T3> IntoOscArgs for (T1, T2, T3)
132where
133 T1: Into<OscType>,
134 T2: Into<OscType>,
135 T3: Into<OscType>,
136{
137 fn into_osc_args(self) -> Vec<OscType> {
138 vec![self.0.into(), self.1.into(), self.2.into()]
139 }
140}
141
142impl IntoOscArgs for OscType {
143 fn into_osc_args(self) -> Vec<OscType> {
144 vec![self]
145 }
146}
147
148pub trait IntoOscPacket {
150 fn into_osc_packet(self) -> OscPacket;
152}
153
154impl IntoOscPacket for OscMessage {
155 fn into_osc_packet(self) -> OscPacket {
156 OscPacket::Message(self)
157 }
158}
159
160impl IntoOscPacket for OscBundle {
161 fn into_osc_packet(self) -> OscPacket {
162 OscPacket::Bundle(self)
163 }
164}
165
166impl IntoOscPacket for OscPacket {
167 fn into_osc_packet(self) -> OscPacket {
168 self
169 }
170}
171
172impl<T> IntoOscPacket for T
173where
174 T: IntoOscMessage,
175{
176 fn into_osc_packet(self) -> OscPacket {
177 OscPacket::Message(self.into_osc_message())
178 }
179}
180
181pub trait IntoOscMessage {
183 fn into_osc_message(self) -> OscMessage;
185}
186
187impl<S, A> IntoOscMessage for (S, A)
188where
189 S: ToString,
190 A: IntoOscArgs,
191{
192 fn into_osc_message(self) -> OscMessage {
193 OscMessage::new(self.0, self.1)
194 }
195}