1use proc_macro::*;
2
3#[proc_macro]
9pub fn pattern(input: TokenStream) -> TokenStream {
10 let input = input.into_iter().collect::<Vec<_>>();
11
12 let string = match &input[..] {
13 [TokenTree::Literal(lit)] => parse_str_literal(&lit),
14 _ => panic!("expected a single string literal to parse"),
15 };
16
17 let pattern = match pattern::parse(&string) {
18 Ok(pattern) => pattern,
19 Err(err) => panic!("invalid pattern syntax: {}", err),
20 };
21
22 format!("{{ use ::pelite::pattern::Atom::*; &{:?} }}", pattern).parse().unwrap()
23}
24
25fn parse_str_literal(input: &Literal) -> String {
26 let input = input.to_string();
27 let mut chars = input.chars();
28 let mut string = String::new();
29 if chars.next() != Some('"') {
30 panic!("expected string literal starting with a `\"` and no extraneous whitespace");
31 }
32 loop {
33 let chr = match chars.next() {
34 Some('\\') => {
35 match chars.next() {
36 Some('\\') => '\\',
37 Some('\'') => '\'',
38 Some('\"') => '\"',
39 Some('t') => '\t',
40 Some('r') => '\r',
41 Some('n') => '\n',
42 Some('u') => panic!("unicode escape sequence not supported"),
43 Some(chr) => panic!("unknown escape sequence: {}", chr),
44 None => panic!(""),
45 }
46 },
47 Some('"') => break,
48 Some(chr) => chr,
49 None => panic!("unexpected end of string literal, missing `\"` terminator?"),
50 };
51 string.push(chr);
52 }
53 string
54}
55
56#[allow(unused)]
58mod pattern;