arr_rs/macros/
helpers.rs

1/// Calculate shape for array creation
2#[macro_export]
3macro_rules! array_parse_shape {
4    ($ndim:expr, $str:expr) => {{
5        let mut shape = Vec::<usize>::new();
6        let mut _string = $str.to_string();
7        for i in (0..$ndim).rev() {
8            let tmp_str = _string.replace(&format!("{},{}", "]".repeat(i), "[".repeat(i)), "]#[");
9            _string = _string[0.._string.find(&"]".repeat(i)).unwrap() + i].to_string();
10            shape.push(tmp_str.split("]#[").count());
11        };
12        shape
13    }};
14}
15
16/// Parse input string and escape special chars array creation
17#[macro_export]
18macro_rules! array_parse_input {
19    ($str:expr) => {{
20        $str.to_string()
21            .replace("\", \"", "\",\"")
22            .replace("], [", "],[")
23            .replace("\\n", "\n")
24            .replace("\\r", "\r")
25            .replace("\\t", "\t")
26            .replace("\\\\", "\\")
27            .replace("\\0", "\0")
28    }};
29}
30
31/// Wrapper for Tuple `array_create!`
32#[macro_export]
33macro_rules! array_tuple {
34    ($tt:ty, $str:expr) => {{
35        let string = array_parse_input!($str);
36        let ndim = string.find(|p| p != '[').unwrap_or(1) - 2;
37        let ndim = if ndim == 0 { 1 } else { ndim };
38
39        let mut tuple_elems = vec![];
40        let mut _string = string.clone();
41        while _string.contains("(") {
42            let start = _string.find("(").unwrap();
43            let end = _string.find(")").unwrap();
44            tuple_elems.push(_string[start..=end].to_string().replace("\"", ""));
45            _string.replace_range(start..=end, "_");
46        }
47
48        // get shape
49        let shape = array_parse_shape!(ndim, _string);
50
51        // get array elements
52        let elems = tuple_elems
53            .into_iter()
54            .map(|e| e.parse().unwrap())
55            .collect::<Vec<_>>();
56
57        // return array
58        Array::<$tt>::new(elems, shape)
59    }};
60}
61
62/// Wrapper for List `array_create!`
63#[macro_export]
64macro_rules! array_list {
65    ($tt:ty, $str:expr) => {{
66        let string = array_parse_input!($str);
67        let ndim = string.find(|p| p != '[').unwrap_or(1) - 2;
68        let ndim = if ndim == 0 { 1 } else { ndim };
69
70        // let mut list_elems = vec![];
71        let mut _string = String::new();
72        let mut nest_level = 0;
73        for c in string.clone().chars() {
74            if c == '[' {
75                nest_level += 1;
76                if nest_level == ndim + 2 { _string.push_str("&["); }
77                else { _string.push(c); }
78            } else if c == ']' {
79                nest_level -= 1;
80                _string.push(c);
81            } else {
82                _string.push(c);
83            }
84        }
85
86        let mut list_elems = vec![];
87        while _string.contains("&") {
88            let start = _string.find("&").unwrap();
89            let end = _string[start + 1..].find("]").unwrap();
90            list_elems.push(_string[start + 2..=start + end].to_string().replace("\"", ""));
91            _string.replace_range(start..=start + end + 1, "_");
92        }
93
94        // get shape
95        let shape = array_parse_shape!(ndim, _string);
96
97        // get array elements
98        let elems = list_elems
99            .into_iter()
100            .map(|e| e.parse().unwrap())
101            .collect::<Vec<$tt>>();
102
103        // return array
104        Array::<$tt>::new(elems, shape)
105    }};
106}
107
108/// Wrapper for char `array_create!`
109#[macro_export]
110macro_rules! array_char {
111    ($str:expr) => {{
112        let string = array_parse_input!($str);
113        let ndim = string.find(|p| p != '[').unwrap_or(1) - 1;
114        let ndim = if ndim == 0 { 1 } else { ndim };
115
116        let mut string_elems = vec![];
117        let mut _string = string.clone();
118        while _string.contains("'") {
119            let start = _string.find("'").unwrap();
120            let end = _string[start + 1..].find("'").unwrap();
121            string_elems.push(_string[start + 1..=start + end].to_string());
122            _string.replace_range(start..=start + end + 1, "_");
123        }
124
125        // get shape
126        let shape = array_parse_shape!(ndim, _string);
127
128        // get array elements
129        let elems = string
130            .replace("[", "").replace("]", "").replace("'", "")
131            .split(",")
132            .map(|e| e.parse().unwrap())
133            .collect::<Vec<_>>();
134
135        // return array
136        Array::<char>::new(elems, shape)
137    }};
138}
139
140/// Wrapper for String `array_create!`
141#[macro_export]
142macro_rules! array_string {
143    ($str:expr) => {{
144        let string = array_parse_input!($str);
145        let ndim = string.find(|p| p != '[').unwrap_or(1) - 1;
146        let ndim = if ndim == 0 { 1 } else { ndim };
147
148        let mut string_elems = vec![];
149        let mut _string = string.clone();
150        while _string.contains("\"") {
151            let start = _string.find("\"").unwrap();
152            let end = _string[start + 1..].find("\"").unwrap();
153            string_elems.push(_string[start + 1..=start + end + 1].to_string().replace("\"", ""));
154            _string.replace_range(start..=start + end + 1, "_");
155        }
156
157        // get shape
158        let shape = array_parse_shape!(ndim, string.clone());
159
160        // get array elements
161        let elems = string
162            .replace("[", "").replace("]", "").replace("\"", "")
163            .split(",")
164            .map(|e| e.to_string())
165            .collect::<Vec<_>>();
166
167        // return array
168        Array::<String>::new(elems, shape)
169    }};
170}