std_mel/ops/option/
block.rs1use futures::{pin_mut, select, FutureExt};
2use melodium_core::*;
3use melodium_macro::mel_treatment;
4
5#[mel_treatment(
9 generic T ()
10 input option Block<Option<T>>
11 output value Block<T>
12)]
13pub async fn unwrap() {
14 if let Ok(pos_val) = option.recv_one().await {
15 match pos_val {
16 Value::Option(Some(val)) => {
17 let _ = value.send_one(*val).await;
18 }
19 _ => {}
20 }
21 }
22}
23
24#[mel_treatment(
28 generic T ()
29 input option Block<Option<T>>
30 output value Block<T>
31)]
32pub async fn unwrap_or(default: T) {
33 if let Ok(pos_val) = option.recv_one().await {
34 match pos_val {
35 Value::Option(Some(val)) => {
36 let _ = value.send_one(*val).await;
37 }
38 Value::Option(None) => {
39 let _ = value.send_one(default).await;
40 }
41 _ => {}
42 }
43 }
44}
45
46#[mel_treatment(
50 generic T ()
51 input value Block<T>
52 output option Block<Option<T>>
53)]
54pub async fn wrap() {
55 if let Ok(val) = value.recv_one().await {
56 let _ = option.send_one(Value::Option(Some(Box::new(val)))).await;
57 }
58}
59
60#[mel_treatment(
66 generic T ()
67 input option Block<Option<T>>
68 output none Block<void>
69 output value Block<T>
70)]
71pub async fn map() {
72 if let Ok(val) = option.recv_one().await {
73 match val {
74 Value::Option(Some(val)) => {
75 let _ = value.send_one(*val).await;
76 }
77 Value::Option(None) => {
78 let _ = none.send_one(().into()).await;
79 }
80 _ => unreachable!(),
81 }
82 }
83}
84
85#[mel_treatment(
91 generic T ()
92 input value Block<T>
93 input none Block<void>
94 output option Block<Option<T>>
95)]
96pub async fn reduce() {
97 let value_arrived = async { (&value).recv_one().await }.fuse();
98 let none_arrived = async { (&none).recv_one().await }.fuse();
99
100 pin_mut!(value_arrived, none_arrived);
101
102 loop {
103 select! {
104 value = value_arrived => {
105 if let Ok(value) = value {
106 let _ = option.send_one(Value::Option(Some(Box::new(value)))).await;
107 break;
108 }
109 },
110 none = none_arrived => {
111 if let Ok(_) = none {
112 let _ = option.send_one(Value::Option(None)).await;
113 break;
114 }
115 },
116 complete => break,
117 };
118 }
119}