parser_fuck/
utils.rs

1use std::ops::Range;
2
3/// Vec<len >= 1>
4pub fn range_of_many1(a: Vec<Range<usize>>) -> Range<usize> {
5    let start = a.first().unwrap().start;
6    let end = a.last().unwrap().end;
7    start..end
8}
9
10/// (Vec<len >= 1>, Vec<len >= 0>)
11pub fn range_of_many1_many((a, b): (Vec<Range<usize>>, Vec<Range<usize>>)) -> Range<usize> {
12    let start = a.first().unwrap().start;
13    let end = if b.is_empty() { a.last() } else { b.last() }.unwrap().end;
14    start..end
15}
16
17/// (Vec<len >= 1>, Vec<len >= 1>)
18pub fn range_of_many1_many1((a, b): (Vec<Range<usize>>, Vec<Range<usize>>)) -> Range<usize> {
19    let start = a.first().unwrap().start;
20    let end = b.last().unwrap().end;
21    start..end
22}
23
24/// (Vec<len >= 0>, Vec<len >= 1>)
25pub fn range_of_many_many1((a, b): (Vec<Range<usize>>, Vec<Range<usize>>)) -> Range<usize> {
26    let start = if a.is_empty() { b.first() } else { a.first() }
27        .unwrap()
28        .start;
29    let end = b.last().unwrap().end;
30    start..end
31}
32
33/// (Vec<len >= 0>, Vec<len >= 0>)
34pub fn range_of_many_many((a, b): (Vec<Range<usize>>, Vec<Range<usize>>)) -> Option<Range<usize>> {
35    if a.is_empty() && b.is_empty() {
36        return None;
37    }
38    let start = if a.is_empty() { b.first() } else { a.first() }
39        .unwrap()
40        .start;
41    let end = if b.is_empty() { a.last() } else { b.last() }.unwrap().end;
42    Some(start..end)
43}
44
45/// (Range, Vec<len >= 0>)
46pub fn range_of_range_many((a, b): (Range<usize>, Vec<Range<usize>>)) -> Range<usize> {
47    let start = a.start;
48    let end = if b.is_empty() {
49        a.end
50    } else {
51        b.last().unwrap().end
52    };
53    start..end
54}
55
56/// (Range, Vec<len >= 0>)
57pub fn range_of_range_many1((a, b): (Range<usize>, Vec<Range<usize>>)) -> Range<usize> {
58    let start = a.start;
59    let end = b.last().unwrap().end;
60    start..end
61}
62
63/// (Vec<len >= 0>, Range)
64pub fn range_of_many1_range((a, b): (Vec<Range<usize>>, Range<usize>)) -> Range<usize> {
65    let start = a.first().unwrap().start;
66    let end = b.end;
67    start..end
68}
69
70/// (Vec<len >= 0>, Range)
71pub fn range_of_many_range((a, b): (Vec<Range<usize>>, Range<usize>)) -> Range<usize> {
72    let start = if a.is_empty() {
73        b.start
74    } else {
75        a.first().unwrap().start
76    };
77    let end = b.end;
78    start..end
79}
80
81/// (Range, Range)
82pub fn range_of_range_range((a, b): (Range<usize>, Range<usize>)) -> Range<usize> {
83    let start = a.start;
84    let end = b.end;
85    start..end
86}
87
88/// (Option<Range>, Range)
89pub fn range_of_optrange_range((a, b): (Option<Range<usize>>, Range<usize>)) -> Range<usize> {
90    let start = if let Some(a) = a { a.start } else { b.start };
91    let end = b.end;
92    start..end
93}
94
95/// (Range, Option<Range>)
96pub fn range_of_range_optrange((a, b): (Range<usize>, Option<Range<usize>>)) -> Range<usize> {
97    let start = a.start;
98    let end = if let Some(b) = b { b.end } else { a.end };
99    start..end
100}
101
102/// (Option<Range>, Option<Range>)
103pub fn range_of_optrange_optrange(
104    (a, b): (Option<Range<usize>>, Option<Range<usize>>),
105) -> Option<Range<usize>> {
106    let start = if a.is_some() { a.clone() } else { b.clone() }.map(|v| v.start)?;
107    let end = if b.is_some() { b } else { a }.map(|v| v.end)?;
108    Some(start..end)
109}
110
111/// try but no return
112/// # Example
113/// ```rust
114/// # use parser_fuck::*;
115/// let a = Some(1);
116/// let r = try_do!(a; Some(v) {
117///     Some(v + 1)
118/// });
119/// assert_eq!(r, Some(2));
120/// ```
121/// ```rust
122/// # use parser_fuck::*;
123/// let a: Result<i32, ()> = Ok(1);
124/// let r = try_do!(a; Ok(v) {
125///     Ok(v + 1)
126/// });
127/// assert_eq!(r, Ok(2));
128/// ```
129#[macro_export(local_inner_macros)]
130macro_rules! try_do {
131    { $v:expr ; Some($n:ident) $b:block } => {
132        match $v {
133            Some($n) => $b
134            None => None
135        }
136    };
137    { $v:expr ; Ok($n:ident) $b:block } => {
138        match $v {
139            Ok($n) => $b
140            Err(err) => Err(err)
141        }
142    };
143}
144
145#[cfg(test)]
146mod tests {
147
148    #[test]
149    fn test_try_do_some() {
150        let a = Some(1);
151        let r = try_do!(a; Some(v) {
152            Some(v + 1)
153        });
154        assert_eq!(r, Some(2));
155    }
156    #[test]
157    fn test_try_do_none() {
158        let a: Option<i32> = None;
159        let r = try_do!(a; Some(v) {
160            Some(v + 1)
161        });
162        assert_eq!(r, None);
163    }
164
165    #[test]
166    fn test_try_do_ok() {
167        let a: Result<i32, ()> = Ok(1);
168        let r = try_do!(a; Ok(v) {
169            Ok(v + 1)
170        });
171        assert_eq!(r, Ok(2));
172    }
173
174    #[test]
175    fn test_try_do_err() {
176        let a: Result<i32, ()> = Err(());
177        let r = try_do!(a; Ok(v) {
178            Ok(v + 1)
179        });
180        assert_eq!(r, Err(()));
181    }
182}