jump_kun_macros/
lib.rs

1extern crate proc_macro;
2extern crate toml;
3
4use dirs::home_dir;
5use proc_macro::TokenStream;
6use quote::quote;
7use std::fs;
8use std::io::{BufReader, Read};
9use std::path::PathBuf;
10use toml::Value;
11
12use syn::{parse_macro_input, DeriveInput};
13
14fn file_open(path: PathBuf) -> Result<String, String> {
15    let mut file_content = String::new();
16
17    let mut fr = fs::File::open(path)
18        .map(|f| BufReader::new(f))
19        .map_err(|e| e.to_string())?;
20
21    fr.read_to_string(&mut file_content)
22        .map_err(|e| e.to_string())?;
23
24    Ok(file_content)
25}
26
27#[proc_macro_derive(order)]
28pub fn order_builder(item: TokenStream) -> TokenStream {
29    let ast = parse_macro_input!(item as DeriveInput);
30    let name = &ast.ident;
31    let enum_variants = if let syn::Data::Enum(syn::DataEnum { variants, .. }) = ast.data {
32        variants
33    } else {
34        unimplemented!();
35    };
36    let enum_len = &enum_variants.len();
37
38    let mut config_dir: PathBuf = home_dir().unwrap();
39    config_dir.push(".config/jump-kun/config.toml".to_string());
40
41    let order_config: String = match file_open(config_dir) {
42        Ok(e) => e.parse::<Value>().unwrap()["order"]
43            .as_str()
44            .unwrap()
45            .to_owned(),
46        Err(_) => "CurrentDir,VisitedDir,ParentDir,ChildDir,NotSure,Invalid".to_string(),
47    };
48
49    let orders: Vec<&str> = order_config.split(",").collect();
50
51    assert_eq!(
52        &orders.len(),
53        enum_len,
54        "orders: {:#?}, enum_variants: {:#?}",
55        orders,
56        enum_variants
57    );
58
59    let enum_fields = orders.iter().enumerate().map(|(i, elm)| {
60        let elm_ident = syn::Ident::new(&elm, name.span());
61        let arm = quote! {
62            #name::#elm_ident => #i as i32,
63        };
64        arm
65    });
66
67    let order_func = quote! {
68        impl #name {
69            pub fn order(&self) -> i32{
70                match self {
71                    #(#enum_fields)*
72                }
73            }
74        }
75    };
76    order_func.into()
77}