megamorse_proc_macro/
lib.rs1extern crate proc_macro;
14use proc_macro::TokenStream;
15
16macro_rules! err {
17 ($e:expr) => {{
18 let err = format!("compile_error!(\"{}\")", $e);
19
20 return err.parse().unwrap();
21 }};
22}
23
24#[proc_macro]
25pub fn morse(item: TokenStream) -> TokenStream {
26 let as_string = item.to_string();
27 let mut parsed_words: Vec<String> = Vec::new();
28
29 let words = as_string.split_whitespace();
30
31 for word in words {
32 if word.len() > 5 {
33 err!(format!(
34 "Word is too long: '{}'.\nMaximum length is 5, actual length is {}",
35 word,
36 word.len()
37 ));
38 }
39
40 let mut codes: Vec<&str> = Vec::with_capacity(as_string.len());
41
42 for c in word.chars() {
43 match c {
44 ' ' => {}
45 '.' => codes.push("megamorse::MorseCode::Dot"),
46 '-' => codes.push("megamorse::MorseCode::Dash"),
47 '_' => codes.push("megamorse::MorseCode::Dash"),
48 _ => err!(format!("Invalid character in morse code: {}", c)),
49 }
50 }
51 let joined = codes.join(", ");
52 let full = format!("megamorse::MorseWord::from([{}])", joined);
53
54 parsed_words.push(full);
55 }
56
57 let joined = parsed_words.join(", ");
58 let out_string = format!("[{}]", joined);
59
60 out_string.parse().unwrap()
61}