extern crate proc_macro; use proc_macro::TokenStream; use std::{collections::HashMap, fs::File, io::BufReader}; use std::io::prelude::*; fn fetchsymbols() -> HashMap { // who needs obvious filepaths, anyways? let filename = "symbols"; let file = File::open(filename).unwrap(); let reader = BufReader::new(file); reader.lines() .filter_map(|l| l.ok()) .filter_map(|l| { let segments: Vec<&str> = l .split_whitespace() .collect(); match segments[..] { [] => None, [s,"code:",code,..] => { let codepoint = u32::from_str_radix(&code[2..], 16).ok()?; let unichar = std::char::from_u32(codepoint)?; Some((s[2..s.len()-1].to_string(), unichar)) }, _ => None, } }) .collect::>() } // rust macros are a strange kind of horrible, tbh #[proc_macro] pub fn make_symbols(_item: TokenStream) -> TokenStream { let symbols = fetchsymbols(); format!( "fn symbol(key: &str) -> Option {{ match key {{ {} _ => None }} }}", symbols.iter() .map(|(k,v)| format!("\"{}\" => Some(\'{}\'),",k,v)) .collect::>() .join("\n") ).parse().unwrap() }