bigquery_functions_types_macros/
lib.rs

1use proc_macro::TokenStream;
2
3/// generate enum Category from `output/categories.json`
4#[proc_macro]
5pub fn enum_category(_item: TokenStream) -> TokenStream {
6    let contents = include_str!("../output/categories.json");
7    let categories: Vec<String> = serde_json::from_str(&contents).unwrap();
8
9    let mut enum_category = String::from("#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]\npub enum Category {\n");
10    for category in &categories {
11        enum_category.push_str(&format!(
12            "    {},\n",
13            category
14        ));
15    }
16    enum_category.push_str("    NoCategory,\n");
17    enum_category.push_str("}");
18
19    enum_category.push_str(
20        "
21impl std::str::FromStr for Category {
22    type Err = ();
23
24    fn from_str(s: &str) -> Result<Self, Self::Err> {
25        match s {
26",
27    );
28    for category in &categories {
29        enum_category.push_str(&format!(
30            "            \"{}\" => Ok(Category::{}),\n",
31            category,
32            category
33        ));
34    }
35    enum_category.push_str(
36        "
37            _ => Err(()),
38        }
39    }
40}
41",
42    );
43
44    // impl Display for Category
45    enum_category.push_str(
46        "
47impl std::fmt::Display for Category {
48    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
49        match self {
50",
51    );
52    for category in &categories {
53        enum_category.push_str(&format!(
54            "            Category::{} => write!(f, \"{}\"),\n",
55            category,
56            category
57        ));
58    }
59    enum_category.push_str(
60        "
61            Category::NoCategory => write!(f, \"NoCategory\"),
62        }
63    }
64}
65",
66    );
67
68    enum_category.parse().unwrap()
69}