text_mel/
compose.rs

1use melodium_core::*;
2use melodium_macro::{check, mel_function, mel_treatment};
3
4/// Rescale stream of strings.
5///
6/// _Rescaling_ means that strings sent throught stream are rearranged according to the `delimiter`.
7///
8/// Unscaled stream can basically be cut at any position:
9/// ```
10/// "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean qua"
11/// "m velit, tristique et arcu in, viverra pulvinar ante. Interdum et m"
12/// "alesuada fames ac ante ipsum primis in faucibus. Cras varius, augue"
13/// " ac fringilla placerat, nibh lorem laoreet enim, sed fermentum libe"
14/// " ro justo ut sapien."
15/// ```
16///
17/// While treatments may expect well-defined strings:
18/// ```
19/// "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
20/// "Aenean quam velit, tristique et arcu in, viverra pulvinar ante."
21/// "Interdum et malesuada fames ac ante ipsum primis in faucibus."
22/// "Cras varius, augue ac fringilla placerat, nibh lorem laoreet enim, sed fermentum libero justo ut sapien."
23/// ```
24#[mel_treatment(
25    default delimiter "\n"
26    input unscaled Stream<string>
27    output scaled Stream<string>
28)]
29pub async fn rescale(delimiter: string) {
30    let mut previous = String::new();
31    'main: while let Ok(input) = unscaled.recv_one_string().await {
32        let splits: Vec<&str> = input.split_inclusive(&delimiter).collect();
33        for split in splits {
34            previous.push_str(split);
35            if previous.ends_with(&delimiter) {
36                check!('main, scaled.send_one_string(previous).await);
37                previous = String::new();
38            }
39        }
40    }
41}
42
43/// Split strings with delimiter.
44///
45/// `text` is splitted according to `delimiter`, and streamed as `splitted` vector.
46/// - `inclusive`: set if the delimiter must be kept at the end of splitted strings (if present).
47///
48/// ```mermaid
49/// graph LR
50///     T("split()")
51///     B["🟦"] -->|vector| T
52///     
53///     T -->|value| O["[🟦 🟦 🟦]"]
54///
55///     style B fill:#ffff,stroke:#ffff
56///     style O fill:#ffff,stroke:#ffff
57/// ```
58#[mel_treatment(
59    default inclusive true
60    input text Stream<string>
61    output splitted Stream<Vec<string>>
62)]
63pub async fn split(delimiter: string, inclusive: bool) {
64    while let Ok(input) = text.recv_string().await {
65        let mut output = Vec::with_capacity(input.len());
66
67        if inclusive {
68            input.into_iter().for_each(|text| {
69                output.push(
70                    text.split_inclusive(&delimiter)
71                        .map(|s| s.to_string())
72                        .collect(),
73                )
74            });
75        } else {
76            input.into_iter().for_each(|text| {
77                output.push(text.split(&delimiter).map(|s| s.to_string()).collect())
78            });
79        }
80
81        check!(splitted.send_vec_string(output).await);
82    }
83}
84
85/// Split strings with delimiter.
86///
87/// `text` is splitted as `Vec<string>` according to `delimiter`.
88/// - `inclusive`: set if the delimiter must be kept at the end of splitted strings (if present).
89#[mel_function(
90    default inclusive true
91)]
92pub fn split(text: string, delimiter: string, inclusive: bool) -> Vec<string> {
93    if inclusive {
94        text.split_inclusive(&delimiter)
95            .map(|s| s.to_string())
96            .collect()
97    } else {
98        text.split(&delimiter).map(|s| s.to_string()).collect()
99    }
100}
101
102/// Trim stream of strings.
103///
104/// Stream strings with leading and trailing whitespace removed.
105/// _Whitespace_ is defined according to the terms of the Unicode Derived Core Property `White_Space`, which includes newlines.
106#[mel_treatment(
107    input text Stream<string>
108    output trimmed Stream<string>
109)]
110pub async fn trim() {
111    while let Ok(mut text) = text.recv_string().await {
112        text.iter_mut().for_each(|t| *t = t.trim().to_string());
113
114        check!(trimmed.send_string(text).await);
115    }
116}
117
118/// Trim string.
119///
120/// Return string with leading and trailing whitespace removed.
121/// _Whitespace_ is defined according to the terms of the Unicode Derived Core Property `White_Space`, which includes newlines.
122#[mel_function]
123pub fn trim(text: string) -> string {
124    text.trim().to_string()
125}