1use melodium_core::{executive::*, *};
2use melodium_macro::{check, mel_data, mel_function, mel_treatment};
3use std::str::FromStr;
4use std::sync::Arc;
5
6#[mel_data(traits(ToString TryToString Display))]
12#[derive(Debug, Clone, Serialize)]
13pub struct Ip(pub std::net::IpAddr);
14
15impl ToString for Ip {
16 fn to_string(&self) -> string {
17 self.0.to_string()
18 }
19}
20
21impl TryToString for Ip {
22 fn try_to_string(&self) -> Option<string> {
23 Some(self.0.to_string())
24 }
25}
26
27impl Display for Ip {
28 fn display(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
29 write!(f, "{}", &self.0)
30 }
31}
32
33#[mel_data(traits(ToString TryToString Display))]
39#[derive(Debug, Clone, Serialize)]
40pub struct Ipv4(pub std::net::Ipv4Addr);
41
42impl ToString for Ipv4 {
43 fn to_string(&self) -> string {
44 self.0.to_string()
45 }
46}
47
48impl TryToString for Ipv4 {
49 fn try_to_string(&self) -> Option<string> {
50 Some(self.0.to_string())
51 }
52}
53
54impl Display for Ipv4 {
55 fn display(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
56 write!(f, "{}", &self.0)
57 }
58}
59
60#[mel_function]
62pub fn from_ipv4(ipv4: Ipv4) -> Ip {
63 Ip(std::net::IpAddr::V4(ipv4.0))
64}
65
66#[mel_function]
68pub fn from_ipv6(ipv6: Ipv6) -> Ip {
69 Ip(std::net::IpAddr::V6(ipv6.0))
70}
71
72#[mel_treatment(
84 input ipv4 Stream<Ipv4>
85 output ip Stream<Ip>
86)]
87pub async fn from_ipv4() {
88 while let Ok(ips) = ipv4
89 .recv_many()
90 .await
91 .map(|values| Into::<VecDeque<Value>>::into(values))
92 {
93 check!(
94 ip.send_many_as(
95 ips.into_iter()
96 .map(|ip| Arc::new(Ip(std::net::IpAddr::V4(
97 ip.try_data::<Arc<Ipv4>>().unwrap().0
98 ))))
99 .collect::<Vec<_>>()
100 )
101 .await
102 )
103 }
104}
105
106#[mel_treatment(
118 input ipv6 Stream<Ipv6>
119 output ip Stream<Ip>
120)]
121pub async fn from_ipv6() {
122 while let Ok(ips) = ipv6
123 .recv_many()
124 .await
125 .map(|values| Into::<VecDeque<Value>>::into(values))
126 {
127 check!(
128 ip.send_many_as(
129 ips.into_iter()
130 .map(|ip| Arc::new(Ip(std::net::IpAddr::V6(
131 ip.try_data::<Arc<Ipv6>>().unwrap().0
132 ))))
133 .collect::<Vec<_>>()
134 )
135 .await
136 )
137 }
138}
139
140#[mel_function]
142pub fn as_ipv4(ip: Ip) -> Option<Ipv4> {
143 if let std::net::IpAddr::V4(ip) = ip.0 {
144 Some(Ipv4(ip))
145 } else {
146 None
147 }
148}
149
150#[mel_function]
152pub fn as_ipv6(ip: Ip) -> Option<Ipv6> {
153 if let std::net::IpAddr::V6(ip) = ip.0 {
154 Some(Ipv6(ip))
155 } else {
156 None
157 }
158}
159
160#[mel_treatment(
174 input ip Stream<Ip>
175 output ipv4 Stream<Option<Ipv4>>
176)]
177pub async fn as_ipv4() {
178 while let Ok(ips) = ip
179 .recv_many()
180 .await
181 .map(|values| Into::<VecDeque<Value>>::into(values))
182 {
183 check!(
184 ipv4.send_many(TransmissionValue::Other(
185 ips.into_iter()
186 .map(
187 |ip| Value::Option(match ip.try_data::<Arc<Ip>>().unwrap().0 {
188 std::net::IpAddr::V4(ip) =>
189 Some(Box::new(Value::Data(Arc::new(Ipv4(ip))))),
190 std::net::IpAddr::V6(_) => None,
191 })
192 )
193 .collect()
194 ))
195 .await
196 )
197 }
198}
199
200#[mel_treatment(
214 input ip Stream<Ip>
215 output ipv6 Stream<Option<Ipv6>>
216)]
217pub async fn as_ipv6() {
218 while let Ok(ips) = ip
219 .recv_many()
220 .await
221 .map(|values| Into::<VecDeque<Value>>::into(values))
222 {
223 check!(
224 ipv6.send_many(TransmissionValue::Other(
225 ips.into_iter()
226 .map(
227 |ip| Value::Option(match ip.try_data::<Arc<Ip>>().unwrap().0 {
228 std::net::IpAddr::V4(_) => None,
229 std::net::IpAddr::V6(ip) =>
230 Some(Box::new(Value::Data(Arc::new(Ipv6(ip))))),
231 })
232 )
233 .collect()
234 ))
235 .await
236 )
237 }
238}
239
240#[mel_function]
242pub fn is_ipv4(ip: Ip) -> bool {
243 ip.0.is_ipv4()
244}
245
246#[mel_function]
248pub fn is_ipv6(ip: Ip) -> bool {
249 ip.0.is_ipv6()
250}
251
252#[mel_treatment(
264 input ip Stream<Ip>
265 output ipv4 Stream<bool>
266)]
267pub async fn is_ipv4() {
268 while let Ok(ips) = ip
269 .recv_many()
270 .await
271 .map(|values| Into::<VecDeque<Value>>::into(values))
272 {
273 check!(
274 ipv4.send_many_as(
275 ips.into_iter()
276 .map(|ip| ip.try_data::<Arc<Ip>>().unwrap().0.is_ipv4())
277 .collect::<Vec<_>>()
278 )
279 .await
280 )
281 }
282}
283
284#[mel_treatment(
296 input ip Stream<Ip>
297 output ipv6 Stream<bool>
298)]
299pub async fn is_ipv6() {
300 while let Ok(ips) = ip
301 .recv_many()
302 .await
303 .map(|values| Into::<VecDeque<Value>>::into(values))
304 {
305 check!(
306 ipv6.send_many_as(
307 ips.into_iter()
308 .map(|ip| ip.try_data::<Arc<Ip>>().unwrap().0.is_ipv6())
309 .collect::<Vec<_>>()
310 )
311 .await
312 )
313 }
314}
315
316#[mel_function]
318pub fn ipv4(a: u8, b: u8, c: u8, d: u8) -> Ipv4 {
319 Ipv4(std::net::Ipv4Addr::new(a, b, c, d))
320}
321
322#[mel_function]
324pub fn to_ipv4(text: string) -> Option<Ipv4> {
325 std::net::Ipv4Addr::from_str(&text).ok().map(|ip| Ipv4(ip))
326}
327
328#[mel_treatment(
342 input text Stream<string>
343 output ipv4 Stream<Option<Ipv4>>
344)]
345pub async fn to_ipv4() {
346 while let Ok(text) = text.recv_many_as::<string>().await {
347 check!(
348 ipv4.send_many(TransmissionValue::Other(
349 text.iter()
350 .map(|t| Value::Option(
351 std::net::Ipv4Addr::from_str(t)
352 .ok()
353 .map(|ip| Box::new(Value::Data(Arc::new(Ipv4(ip)))))
354 ))
355 .collect()
356 ))
357 .await
358 )
359 }
360}
361
362#[mel_function]
364pub fn localhost_ipv4() -> Ipv4 {
365 Ipv4(std::net::Ipv4Addr::LOCALHOST)
366}
367
368#[mel_function]
370pub fn unspecified_ipv4() -> Ipv4 {
371 Ipv4(std::net::Ipv4Addr::UNSPECIFIED)
372}
373
374#[mel_data(traits(ToString TryToString Display))]
380#[derive(Debug, Clone, Serialize)]
381pub struct Ipv6(pub std::net::Ipv6Addr);
382
383impl ToString for Ipv6 {
384 fn to_string(&self) -> string {
385 self.0.to_string()
386 }
387}
388
389impl TryToString for Ipv6 {
390 fn try_to_string(&self) -> Option<string> {
391 Some(self.0.to_string())
392 }
393}
394
395impl Display for Ipv6 {
396 fn display(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
397 write!(f, "{}", &self.0)
398 }
399}
400
401#[mel_function]
403pub fn ipv6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6 {
404 Ipv6(std::net::Ipv6Addr::new(a, b, c, d, e, f, g, h))
405}
406
407#[mel_function]
409pub fn to_ipv6(text: string) -> Option<Ipv6> {
410 std::net::Ipv6Addr::from_str(&text).ok().map(|ip| Ipv6(ip))
411}
412
413#[mel_treatment(
427 input text Stream<string>
428 output ipv6 Stream<Option<Ipv6>>
429)]
430pub async fn to_ipv6() {
431 while let Ok(text) = text.recv_many_as::<string>().await {
432 check!(
433 ipv6.send_many(TransmissionValue::Other(
434 text.iter()
435 .map(|t| Value::Option(
436 std::net::Ipv6Addr::from_str(t)
437 .ok()
438 .map(|ip| Box::new(Value::Data(Arc::new(Ipv6(ip)))))
439 ))
440 .collect()
441 ))
442 .await
443 )
444 }
445}
446
447#[mel_function]
449pub fn localhost_ipv6() -> Ipv6 {
450 Ipv6(std::net::Ipv6Addr::LOCALHOST)
451}
452
453#[mel_function]
455pub fn unspecified_ipv6() -> Ipv6 {
456 Ipv6(std::net::Ipv6Addr::UNSPECIFIED)
457}