1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use proc_macro2::{TokenStream, TokenTree};
use quote::ToTokens;
use std::fmt::Debug;
use syn::parse::{Parse, ParseStream};
use syn::{parse2, Expr};
use super::unit::{Unit, UnitResult};
use crate::chain::group::{ActionGroup, ApplicationType, Combinator, GroupDeterminer, MoveType};
pub fn is_valid_expr(input: TokenStream) -> bool {
is_valid_stream::<Expr>(input)
}
pub fn is_valid_stream<T: Parse>(input: TokenStream) -> bool {
syn::parse2::<T>(input).is_ok()
}
pub fn is_block_expr(expr: &Expr) -> bool {
matches!(expr, Expr::Block(_))
}
pub fn parse_until<'a, T: Parse + Clone + Debug>(
input: ParseStream<'_>,
group_determiners: impl Iterator<Item = &'a GroupDeterminer> + Clone,
deferred_determiner: &'a GroupDeterminer,
wrapper_determiner: &'a GroupDeterminer,
allow_empty_parsed: bool,
) -> UnitResult<T, ActionGroup> {
let group_count = group_determiners.clone().count();
let mut group_determiners = group_determiners.cycle();
let mut tokens = TokenStream::new();
let mut next = None;
let mut deferred = false;
let mut wrap = false;
while !input.is_empty()
&& !{
let group_determiners = &mut group_determiners;
deferred = deferred_determiner.check_input(input);
if deferred {
deferred_determiner.erase_input(input)?;
}
let possible_group = group_determiners
.take(group_count)
.find(|group| group.check_input(input));
possible_group
.map(|group| {
tokens.is_empty() && allow_empty_parsed
|| group.check_parsed::<T>(tokens.clone())
})
.unwrap_or(false)
&& {
next = possible_group;
true
}
}
{
let next: TokenTree = input.parse()?;
next.to_tokens(&mut tokens);
}
if let Some(group) = next {
if let Some(combinator) = group.combinator() {
let forked = input.fork();
group.erase_input(&forked)?;
wrap = wrapper_determiner.check_input(&forked);
if wrap && combinator == Combinator::UNWRAP {
return Err(input.error("Action can be either wrapped or unwrapped but not both"));
} else if wrap && !combinator.can_be_wrapper() {
return Err(input.error("This combinator can't be wrapper"));
}
if wrap {
wrapper_determiner.erase_input(input)?;
}
}
group.erase_input(input)?;
}
Ok(Unit {
parsed: parse2(tokens)?,
next: next.and_then(|group| {
group.combinator().map(|combinator| {
ActionGroup::new(
combinator,
if deferred {
ApplicationType::Deferred
} else {
ApplicationType::Instant
},
if wrap {
MoveType::Wrap
} else if combinator == Combinator::UNWRAP {
MoveType::Unwrap
} else {
MoveType::None
},
)
})
}),
})
}
pub fn skip(input: ParseStream<'_>) -> bool {
input
.step(|cursor| {
if let Some((_lifetime, rest)) = cursor.lifetime() {
Ok((true, rest))
} else if let Some((_token, rest)) = cursor.token_tree() {
Ok((true, rest))
} else {
Ok((false, *cursor))
}
})
.unwrap()
}