1#![feature(fs_try_exists)]
38use std::io::{Read, Write};
39
40use proc_macro::TokenStream;
41use syn::parse_macro_input;
42use syn::DeriveInput;
43mod to_snake_case;
44use to_snake_case::ToSnakeCase;
45#[proc_macro_derive(GameStates)]
47pub fn game_states(input: proc_macro::TokenStream) -> TokenStream {
48 let input = parse_macro_input!(input as DeriveInput);
49 let enum_name: &str = &input.ident.to_string();
50
51 let path_name: &str=&ToSnakeCase::new(enum_name).collect::<String>();
53 if !std::fs::try_exists(String::from("src/") + path_name).unwrap() {
55 std::fs::create_dir_all(String::from("src/") + path_name + "/config").unwrap();
57
58 let mut mod_rs_file = std::fs::File::options()
60 .write(true)
61 .create(true)
62 .open(String::from("src/") + path_name + "/mod.rs")
63 .unwrap();
64 let mut file = std::fs::File::options()
66 .write(true)
67 .create(true)
68 .open(String::from("src/") + path_name + "/config/info.txt")
69 .unwrap();
70
71 let mut init_file = std::fs::File::options()
73 .write(true)
74 .create(true)
75 .open(String::from("src/") + path_name + "/config/init.txt")
76 .unwrap();
77 writeln!(init_file, "app.add_loopless_state(*self)").unwrap();
78
79 match input.data {
81 syn::Data::Enum(ref data_struct) => {
83 for variant in &data_struct.variants {
84 let variant_name: &str = &variant.ident.to_string();
86 let struct_file_name: &str=&ToSnakeCase::new(variant_name).collect::<String>();
88 writeln!(file, "{}", variant_name).unwrap();
90 writeln!(init_file, ".add_plugin({})", variant_name).unwrap();
91 writeln!(mod_rs_file, "mod {};", struct_file_name).unwrap();
92 writeln!(mod_rs_file, "use {}::{};", struct_file_name, variant_name).unwrap();
93 create_file(path_name,struct_file_name,enum_name, variant_name).unwrap();
94 }
95 }
96 _ => (),
97 }
98 let over_string = include_str!("../template_mod.txt").replace("$", enum_name);
99 write!(mod_rs_file, "{}", over_string).unwrap();
100 file.flush().unwrap();
101 init_file.flush().unwrap();
102 mod_rs_file.flush().unwrap();
103 } else {
104 let mut file = std::fs::File::options()
106 .read(true)
107 .write(true)
108 .open(String::from("src/") + path_name + "/config/info.txt")
109 .unwrap();
110
111 let mut mod_rs_file = std::fs::File::options()
113 .append(true)
114 .open(String::from("src/") + path_name + "/mod.rs")
115 .unwrap();
116
117 let mut init_file = std::fs::File::options()
119 .append(true)
120 .open(String::from("src/") + path_name + "/config/init.txt")
121 .unwrap();
122
123 let mut file_str = String::new();
125 file.read_to_string(&mut file_str).unwrap();
126 let arr = file_str.split('\n').collect::<Vec<_>>();
127 match input.data {
128 syn::Data::Enum(ref data_struct) => {
130 for variant in &data_struct.variants {
131 let variant_name: &str = &variant.ident.to_string();
133 let struct_file_name: &str = &variant_name.to_ascii_lowercase();
134 if !arr.contains(&variant_name) {
137 writeln!(file, "{}", variant_name).unwrap();
139 writeln!(init_file, ".add_plugin({})", variant_name).unwrap();
140 writeln!(mod_rs_file, "mod {};", struct_file_name).unwrap();
141 writeln!(mod_rs_file, "use {}::{};", struct_file_name, variant_name).unwrap();
142 create_file(path_name,struct_file_name,enum_name, variant_name).unwrap();
143 }
144 }
145 }
146 _ => (),
147 }
148 file.flush().unwrap();
149 init_file.flush().unwrap();
150 mod_rs_file.flush().unwrap();
151 }
152
153 TokenStream::new()
154}
155
156#[inline]
158fn create_file(path: &str, file_name: &str,enum_name:&str,struct_name:&str) -> std::io::Result<()> {
159 let mut struct_file = std::fs::File::create(
160 String::from("src/")
161 + &path
162 + "/"
163 + &file_name
164 + ".rs",
165 )?;
166 let over_str = include_str!("../template.txt")
167 .replace("$", enum_name)
168 .replace("~", struct_name);
169 write!(struct_file, "{}", over_str)
170}