forked from Peternator7/strum
/
helpers.rs
97 lines (89 loc) · 3.09 KB
/
helpers.rs
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
use heck::{CamelCase, KebabCase, MixedCase, ShoutySnakeCase, SnakeCase, TitleCase};
use syn::{Attribute, Ident, Meta};
use case_style::CaseStyle;
pub fn extract_meta(attrs: &[Attribute]) -> Vec<Meta> {
attrs
.iter()
.filter_map(|attribute| attribute.interpret_meta())
.collect()
}
pub fn extract_meta_attrs<'meta>(meta: &'meta [Meta], attr: &str) -> Vec<&'meta Ident> {
use syn::NestedMeta;
meta.iter()
// Get all the attributes with our tag on them.
.filter_map(|meta| match *meta {
Meta::List(ref metalist) => {
if metalist.ident == attr {
Some(&metalist.nested)
} else {
None
}
}
_ => None,
}).flat_map(|nested| nested)
// Get all the inner elements as long as they start with ser.
.filter_map(|meta| match *meta {
NestedMeta::Meta(Meta::Word(ref ident)) => Some(ident),
_ => None,
}).collect()
}
pub fn extract_attrs(meta: &[Meta], attr: &str, prop: &str) -> Vec<String> {
use syn::{Lit, MetaNameValue, NestedMeta};
meta.iter()
// Get all the attributes with our tag on them.
.filter_map(|meta| match *meta {
Meta::List(ref metalist) => {
if metalist.ident == attr {
Some(&metalist.nested)
} else {
None
}
}
_ => None,
}).flat_map(|nested| nested)
// Get all the inner elements as long as they start with ser.
.filter_map(|meta| match *meta {
NestedMeta::Meta(Meta::NameValue(MetaNameValue {
ref ident,
lit: Lit::Str(ref s),
..
})) => {
if ident == prop {
Some(s.value())
} else {
None
}
}
_ => None,
}).collect()
}
pub fn unique_attr(attrs: &[Meta], attr: &str, prop: &str) -> Option<String> {
let mut curr = extract_attrs(attrs, attr, prop);
if curr.len() > 1 {
panic!("More than one property: {} found on variant", prop);
}
curr.pop()
}
pub fn is_disabled(attrs: &[Meta]) -> bool {
let v = extract_attrs(attrs, "strum", "disabled");
match v.len() {
0 => false,
1 => v[0] == "true",
_ => panic!("Can't have multiple values for 'disabled'"),
}
}
pub fn convert_case(ident: &Ident, case_style: Option<CaseStyle>) -> String {
let ident_string = ident.to_string();
if let Some(case_style) = case_style {
match case_style {
CaseStyle::CamelCase => ident_string.to_camel_case(),
CaseStyle::KebabCase => ident_string.to_kebab_case(),
CaseStyle::MixedCase => ident_string.to_mixed_case(),
CaseStyle::ShoutySnakeCase => ident_string.to_shouty_snake_case(),
CaseStyle::SnakeCase => ident_string.to_snake_case(),
CaseStyle::TitleCase => ident_string.to_title_case(),
}
} else {
ident_string
}
}