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(TransmissionValue::Other(
95 ips.into_iter()
96 .map(|ip| Value::Data(Arc::new(Ip(std::net::IpAddr::V4(
97 GetData::<Arc<dyn Data>>::try_data(ip)
98 .unwrap()
99 .downcast_arc::<Ipv4>()
100 .unwrap()
101 .0
102 )))))
103 .collect()
104 ))
105 .await
106 )
107 }
108}
109
110#[mel_treatment(
122 input ipv6 Stream<Ipv6>
123 output ip Stream<Ip>
124)]
125pub async fn from_ipv6() {
126 while let Ok(ips) = ipv6
127 .recv_many()
128 .await
129 .map(|values| Into::<VecDeque<Value>>::into(values))
130 {
131 check!(
132 ip.send_many(TransmissionValue::Other(
133 ips.into_iter()
134 .map(|ip| Value::Data(Arc::new(Ip(std::net::IpAddr::V6(
135 GetData::<Arc<dyn Data>>::try_data(ip)
136 .unwrap()
137 .downcast_arc::<Ipv6>()
138 .unwrap()
139 .0
140 )))))
141 .collect()
142 ))
143 .await
144 )
145 }
146}
147
148#[mel_function]
150pub fn as_ipv4(ip: Ip) -> Option<Ipv4> {
151 if let std::net::IpAddr::V4(ip) = ip.0 {
152 Some(Ipv4(ip))
153 } else {
154 None
155 }
156}
157
158#[mel_function]
160pub fn as_ipv6(ip: Ip) -> Option<Ipv6> {
161 if let std::net::IpAddr::V6(ip) = ip.0 {
162 Some(Ipv6(ip))
163 } else {
164 None
165 }
166}
167
168#[mel_treatment(
182 input ip Stream<Ip>
183 output ipv4 Stream<Option<Ipv4>>
184)]
185pub async fn as_ipv4() {
186 while let Ok(ips) = ip
187 .recv_many()
188 .await
189 .map(|values| Into::<VecDeque<Value>>::into(values))
190 {
191 check!(
192 ipv4.send_many(TransmissionValue::Other(
193 ips.into_iter()
194 .map(|ip| Value::Option(
195 match GetData::<Arc<dyn Data>>::try_data(ip)
196 .unwrap()
197 .downcast_arc::<Ip>()
198 .unwrap()
199 .0
200 {
201 std::net::IpAddr::V4(ip) =>
202 Some(Box::new(Value::Data(Arc::new(Ipv4(ip))))),
203 std::net::IpAddr::V6(_) => None,
204 }
205 ))
206 .collect()
207 ))
208 .await
209 )
210 }
211}
212
213#[mel_treatment(
227 input ip Stream<Ip>
228 output ipv6 Stream<Option<Ipv6>>
229)]
230pub async fn as_ipv6() {
231 while let Ok(ips) = ip
232 .recv_many()
233 .await
234 .map(|values| Into::<VecDeque<Value>>::into(values))
235 {
236 check!(
237 ipv6.send_many(TransmissionValue::Other(
238 ips.into_iter()
239 .map(|ip| Value::Option(
240 match GetData::<Arc<dyn Data>>::try_data(ip)
241 .unwrap()
242 .downcast_arc::<Ip>()
243 .unwrap()
244 .0
245 {
246 std::net::IpAddr::V4(_) => None,
247 std::net::IpAddr::V6(ip) =>
248 Some(Box::new(Value::Data(Arc::new(Ipv6(ip))))),
249 }
250 ))
251 .collect()
252 ))
253 .await
254 )
255 }
256}
257
258#[mel_function]
260pub fn is_ipv4(ip: Ip) -> bool {
261 ip.0.is_ipv4()
262}
263
264#[mel_function]
266pub fn is_ipv6(ip: Ip) -> bool {
267 ip.0.is_ipv6()
268}
269
270#[mel_treatment(
282 input ip Stream<Ip>
283 output ipv4 Stream<bool>
284)]
285pub async fn is_ipv4() {
286 while let Ok(ips) = ip
287 .recv_many()
288 .await
289 .map(|values| Into::<VecDeque<Value>>::into(values))
290 {
291 check!(
292 ipv4.send_many(TransmissionValue::Bool(
293 ips.into_iter()
294 .map(|ip| GetData::<Arc<dyn Data>>::try_data(ip)
295 .unwrap()
296 .downcast_arc::<Ip>()
297 .unwrap()
298 .0
299 .is_ipv4())
300 .collect()
301 ))
302 .await
303 )
304 }
305}
306
307#[mel_treatment(
319 input ip Stream<Ip>
320 output ipv6 Stream<bool>
321)]
322pub async fn is_ipv6() {
323 while let Ok(ips) = ip
324 .recv_many()
325 .await
326 .map(|values| Into::<VecDeque<Value>>::into(values))
327 {
328 check!(
329 ipv6.send_many(TransmissionValue::Bool(
330 ips.into_iter()
331 .map(|ip| GetData::<Arc<dyn Data>>::try_data(ip)
332 .unwrap()
333 .downcast_arc::<Ip>()
334 .unwrap()
335 .0
336 .is_ipv6())
337 .collect()
338 ))
339 .await
340 )
341 }
342}
343
344#[mel_function]
346pub fn ipv4(a: u8, b: u8, c: u8, d: u8) -> Ipv4 {
347 Ipv4(std::net::Ipv4Addr::new(a, b, c, d))
348}
349
350#[mel_function]
352pub fn to_ipv4(text: string) -> Option<Ipv4> {
353 std::net::Ipv4Addr::from_str(&text).ok().map(|ip| Ipv4(ip))
354}
355
356#[mel_treatment(
370 input text Stream<string>
371 output ipv4 Stream<Option<Ipv4>>
372)]
373pub async fn to_ipv4() {
374 while let Ok(text) = text
375 .recv_many()
376 .await
377 .map(|values| TryInto::<Vec<string>>::try_into(values).unwrap())
378 {
379 check!(
380 ipv4.send_many(TransmissionValue::Other(
381 text.iter()
382 .map(|t| Value::Option(
383 std::net::Ipv4Addr::from_str(t)
384 .ok()
385 .map(|ip| Box::new(Value::Data(Arc::new(Ipv4(ip)))))
386 ))
387 .collect()
388 ))
389 .await
390 )
391 }
392}
393
394#[mel_function]
396pub fn localhost_ipv4() -> Ipv4 {
397 Ipv4(std::net::Ipv4Addr::LOCALHOST)
398}
399
400#[mel_function]
402pub fn unspecified_ipv4() -> Ipv4 {
403 Ipv4(std::net::Ipv4Addr::UNSPECIFIED)
404}
405
406#[mel_data(traits(ToString TryToString Display))]
412#[derive(Debug, Clone, Serialize)]
413pub struct Ipv6(pub std::net::Ipv6Addr);
414
415impl ToString for Ipv6 {
416 fn to_string(&self) -> string {
417 self.0.to_string()
418 }
419}
420
421impl TryToString for Ipv6 {
422 fn try_to_string(&self) -> Option<string> {
423 Some(self.0.to_string())
424 }
425}
426
427impl Display for Ipv6 {
428 fn display(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
429 write!(f, "{}", &self.0)
430 }
431}
432
433#[mel_function]
435pub fn ipv6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6 {
436 Ipv6(std::net::Ipv6Addr::new(a, b, c, d, e, f, g, h))
437}
438
439#[mel_function]
441pub fn to_ipv6(text: string) -> Option<Ipv6> {
442 std::net::Ipv6Addr::from_str(&text).ok().map(|ip| Ipv6(ip))
443}
444
445#[mel_treatment(
459 input text Stream<string>
460 output ipv6 Stream<Option<Ipv6>>
461)]
462pub async fn to_ipv6() {
463 while let Ok(text) = text
464 .recv_many()
465 .await
466 .map(|values| TryInto::<Vec<string>>::try_into(values).unwrap())
467 {
468 check!(
469 ipv6.send_many(TransmissionValue::Other(
470 text.iter()
471 .map(|t| Value::Option(
472 std::net::Ipv6Addr::from_str(t)
473 .ok()
474 .map(|ip| Box::new(Value::Data(Arc::new(Ipv6(ip)))))
475 ))
476 .collect()
477 ))
478 .await
479 )
480 }
481}
482
483#[mel_function]
485pub fn localhost_ipv6() -> Ipv6 {
486 Ipv6(std::net::Ipv6Addr::LOCALHOST)
487}
488
489#[mel_function]
491pub fn unspecified_ipv6() -> Ipv6 {
492 Ipv6(std::net::Ipv6Addr::UNSPECIFIED)
493}