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
use syn::{
braced, parenthesized,
parse::{Parse, ParseBuffer, ParseStream},
token, Ident, Result, Token,
};
use crate::util;
use crate::widgets::{Widget, WidgetFunc};
impl Parse for Widget {
fn parse(input: ParseStream) -> Result<Self> {
let mut name_opt: Option<Ident> = None;
let mutable = input.parse().ok();
if input.peek2(Token![=]) {
name_opt = Some(input.parse()?);
let _token: Token![=] = input.parse()?;
};
let inner_input: Option<ParseBuffer>;
let upcomming_some = {
let forked_input = input.fork();
if forked_input.peek(Ident) {
let ident: Ident = forked_input.parse()?;
ident == "Some"
} else {
false
}
};
let wrapper = if upcomming_some && input.peek2(token::Paren) {
let ident = input.parse()?;
let paren_input;
parenthesized!(paren_input in input);
inner_input = Some(paren_input);
Some(ident)
} else {
inner_input = None;
None
};
let func_input = if let Some(paren_input) = &inner_input {
paren_input
} else {
input
};
let ref_token = func_input.parse().ok();
let deref_token = func_input.parse().ok();
let func: WidgetFunc = func_input.parse()?;
let inner;
let _token = braced!(inner in input);
let properties = inner.parse()?;
let name = if let Some(name) = name_opt {
name
} else {
util::idents_to_snake_case(&func.path_segments, func.span)
};
let returned_widget = if input.peek(Token![->]) {
let _arrow: Token![->] = input.parse()?;
Some(input.parse()?)
} else {
None
};
Ok(Widget {
mutable,
name,
func,
properties,
wrapper,
ref_token,
deref_token,
returned_widget,
})
}
}