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(
74 input ipv4 Stream<Ipv4>
75 output ip Stream<Ip>
76)]
77pub async fn from_ipv4() {
78 while let Ok(ips) = ipv4
79 .recv_many()
80 .await
81 .map(|values| Into::<VecDeque<Value>>::into(values))
82 {
83 check!(
84 ip.send_many(TransmissionValue::Other(
85 ips.into_iter()
86 .map(|ip| Value::Data(Arc::new(Ip(std::net::IpAddr::V4(
87 GetData::<Arc<dyn Data>>::try_data(ip)
88 .unwrap()
89 .downcast_arc::<Ipv4>()
90 .unwrap()
91 .0
92 )))))
93 .collect()
94 ))
95 .await
96 )
97 }
98}
99
100#[mel_treatment(
102 input ipv6 Stream<Ipv6>
103 output ip Stream<Ip>
104)]
105pub async fn from_ipv6() {
106 while let Ok(ips) = ipv6
107 .recv_many()
108 .await
109 .map(|values| Into::<VecDeque<Value>>::into(values))
110 {
111 check!(
112 ip.send_many(TransmissionValue::Other(
113 ips.into_iter()
114 .map(|ip| Value::Data(Arc::new(Ip(std::net::IpAddr::V6(
115 GetData::<Arc<dyn Data>>::try_data(ip)
116 .unwrap()
117 .downcast_arc::<Ipv6>()
118 .unwrap()
119 .0
120 )))))
121 .collect()
122 ))
123 .await
124 )
125 }
126}
127
128#[mel_function]
130pub fn as_ipv4(ip: Ip) -> Option<Ipv4> {
131 if let std::net::IpAddr::V4(ip) = ip.0 {
132 Some(Ipv4(ip))
133 } else {
134 None
135 }
136}
137
138#[mel_function]
140pub fn as_ipv6(ip: Ip) -> Option<Ipv6> {
141 if let std::net::IpAddr::V6(ip) = ip.0 {
142 Some(Ipv6(ip))
143 } else {
144 None
145 }
146}
147
148#[mel_treatment(
150 input ip Stream<Ip>
151 output ipv4 Stream<Option<Ipv4>>
152)]
153pub async fn as_ipv4() {
154 while let Ok(ips) = ip
155 .recv_many()
156 .await
157 .map(|values| Into::<VecDeque<Value>>::into(values))
158 {
159 check!(
160 ipv4.send_many(TransmissionValue::Other(
161 ips.into_iter()
162 .map(|ip| Value::Option(
163 match GetData::<Arc<dyn Data>>::try_data(ip)
164 .unwrap()
165 .downcast_arc::<Ip>()
166 .unwrap()
167 .0
168 {
169 std::net::IpAddr::V4(ip) =>
170 Some(Box::new(Value::Data(Arc::new(Ipv4(ip))))),
171 std::net::IpAddr::V6(_) => None,
172 }
173 ))
174 .collect()
175 ))
176 .await
177 )
178 }
179}
180
181#[mel_treatment(
183 input ip Stream<Ip>
184 output ipv6 Stream<Option<Ipv6>>
185)]
186pub async fn as_ipv6() {
187 while let Ok(ips) = ip
188 .recv_many()
189 .await
190 .map(|values| Into::<VecDeque<Value>>::into(values))
191 {
192 check!(
193 ipv6.send_many(TransmissionValue::Other(
194 ips.into_iter()
195 .map(|ip| Value::Option(
196 match GetData::<Arc<dyn Data>>::try_data(ip)
197 .unwrap()
198 .downcast_arc::<Ip>()
199 .unwrap()
200 .0
201 {
202 std::net::IpAddr::V4(_) => None,
203 std::net::IpAddr::V6(ip) =>
204 Some(Box::new(Value::Data(Arc::new(Ipv6(ip))))),
205 }
206 ))
207 .collect()
208 ))
209 .await
210 )
211 }
212}
213
214#[mel_function]
216pub fn is_ipv4(ip: Ip) -> bool {
217 ip.0.is_ipv4()
218}
219
220#[mel_function]
222pub fn is_ipv6(ip: Ip) -> bool {
223 ip.0.is_ipv6()
224}
225
226#[mel_treatment(
228 input ip Stream<Ip>
229 output ipv4 Stream<bool>
230)]
231pub async fn is_ipv4() {
232 while let Ok(ips) = ip
233 .recv_many()
234 .await
235 .map(|values| Into::<VecDeque<Value>>::into(values))
236 {
237 check!(
238 ipv4.send_many(TransmissionValue::Bool(
239 ips.into_iter()
240 .map(|ip| GetData::<Arc<dyn Data>>::try_data(ip)
241 .unwrap()
242 .downcast_arc::<Ip>()
243 .unwrap()
244 .0
245 .is_ipv4())
246 .collect()
247 ))
248 .await
249 )
250 }
251}
252
253#[mel_treatment(
255 input ip Stream<Ip>
256 output ipv6 Stream<bool>
257)]
258pub async fn is_ipv6() {
259 while let Ok(ips) = ip
260 .recv_many()
261 .await
262 .map(|values| Into::<VecDeque<Value>>::into(values))
263 {
264 check!(
265 ipv6.send_many(TransmissionValue::Bool(
266 ips.into_iter()
267 .map(|ip| GetData::<Arc<dyn Data>>::try_data(ip)
268 .unwrap()
269 .downcast_arc::<Ip>()
270 .unwrap()
271 .0
272 .is_ipv6())
273 .collect()
274 ))
275 .await
276 )
277 }
278}
279
280#[mel_function]
282pub fn ipv4(a: u8, b: u8, c: u8, d: u8) -> Ipv4 {
283 Ipv4(std::net::Ipv4Addr::new(a, b, c, d))
284}
285
286#[mel_function]
288pub fn to_ipv4(text: string) -> Option<Ipv4> {
289 std::net::Ipv4Addr::from_str(&text).ok().map(|ip| Ipv4(ip))
290}
291
292#[mel_treatment(
296 input text Stream<string>
297 output ipv4 Stream<Option<Ipv4>>
298)]
299pub async fn to_ipv4() {
300 while let Ok(text) = text
301 .recv_many()
302 .await
303 .map(|values| TryInto::<Vec<string>>::try_into(values).unwrap())
304 {
305 check!(
306 ipv4.send_many(TransmissionValue::Other(
307 text.iter()
308 .map(|t| Value::Option(
309 std::net::Ipv4Addr::from_str(t)
310 .ok()
311 .map(|ip| Box::new(Value::Data(Arc::new(Ipv4(ip)))))
312 ))
313 .collect()
314 ))
315 .await
316 )
317 }
318}
319
320#[mel_function]
322pub fn localhost_ipv4() -> Ipv4 {
323 Ipv4(std::net::Ipv4Addr::LOCALHOST)
324}
325
326#[mel_function]
328pub fn unspecified_ipv4() -> Ipv4 {
329 Ipv4(std::net::Ipv4Addr::UNSPECIFIED)
330}
331
332#[mel_data(traits(ToString TryToString Display))]
338#[derive(Debug, Clone, Serialize)]
339pub struct Ipv6(pub std::net::Ipv6Addr);
340
341impl ToString for Ipv6 {
342 fn to_string(&self) -> string {
343 self.0.to_string()
344 }
345}
346
347impl TryToString for Ipv6 {
348 fn try_to_string(&self) -> Option<string> {
349 Some(self.0.to_string())
350 }
351}
352
353impl Display for Ipv6 {
354 fn display(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
355 write!(f, "{}", &self.0)
356 }
357}
358
359#[mel_function]
361pub fn ipv6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6 {
362 Ipv6(std::net::Ipv6Addr::new(a, b, c, d, e, f, g, h))
363}
364
365#[mel_function]
367pub fn to_ipv6(text: string) -> Option<Ipv6> {
368 std::net::Ipv6Addr::from_str(&text).ok().map(|ip| Ipv6(ip))
369}
370
371#[mel_treatment(
375 input text Stream<string>
376 output ipv6 Stream<Option<Ipv6>>
377)]
378pub async fn to_ipv6() {
379 while let Ok(text) = text
380 .recv_many()
381 .await
382 .map(|values| TryInto::<Vec<string>>::try_into(values).unwrap())
383 {
384 check!(
385 ipv6.send_many(TransmissionValue::Other(
386 text.iter()
387 .map(|t| Value::Option(
388 std::net::Ipv6Addr::from_str(t)
389 .ok()
390 .map(|ip| Box::new(Value::Data(Arc::new(Ipv6(ip)))))
391 ))
392 .collect()
393 ))
394 .await
395 )
396 }
397}
398
399#[mel_function]
401pub fn localhost_ipv6() -> Ipv6 {
402 Ipv6(std::net::Ipv6Addr::LOCALHOST)
403}
404
405#[mel_function]
407pub fn unspecified_ipv6() -> Ipv6 {
408 Ipv6(std::net::Ipv6Addr::UNSPECIFIED)
409}