1extern crate proc_macro;
2use std::vec;
3use proc_macro::TokenStream;
4use quote::quote;
5use regex::Regex;
6use syn::{parse_macro_input, DeriveInput, Fields};
7use proc_macro2::{Ident, Span};
8#[proc_macro_attribute]
9pub fn auto_json_db(_attr: TokenStream, item: TokenStream) -> TokenStream {
10 let input = parse_macro_input!(item as DeriveInput);
11
12 let name = &input.ident;
13 let name_behalf = Ident::new(&format!("{}_behalf", name), Span::call_site());
14
15 let fields = match &input.data {
16 syn::Data::Struct(syn::DataStruct { fields: Fields::Named(fields), .. }) => fields,
17 _ => panic!("auto_id macro can only be used on structs with named fields"),
18 };
19 let field_names: Vec<_> = fields.named.iter().map(|f| &f.ident).collect();
20 let field_types: Vec<_> = fields.named.iter().map(|f| &f.ty).collect();
21
22 let binding = _attr.to_string();
23 let attribute_hm = parse_string_to_hashmap(&binding);
24 let encript_name = attribute_hm.get("encript").unwrap_or(&"".to_owned()).to_owned();
25
26 let mut unique_field_len = 0;
27 let mut unique_field: Vec<_> = vec![];
28 let mut unique_field_types: Vec<_> = vec![];
29 if let Some(unique_field_string) = attribute_hm.get("unique"){
30 unique_field = unique_field_string.split("|").map(|s| {
31 if !s.trim().is_empty() {
32 Some(Ident::new(s.trim(), Span::call_site()))
33 }else{
34 None
35 }
36 } ).collect();
37 unique_field_len = unique_field.len();
38 unique_field.iter().for_each(|f| {
39 if let Some(field_name) = f {
40 if let Some(index) = field_names.iter().position(|&r| r.clone().unwrap().to_string() == field_name.to_string() ) {
41 unique_field_types.push(field_types[index].clone());
42 }
43 }
44 });
45 }
46
47 let mut is_complex = false;
48 if attribute_hm.get("bigsize").is_some(){
49 is_complex = true;
50 }
51 let mut is_singleton = false;
52 if attribute_hm.get("singleton").is_some(){
53 is_singleton = true;
54 }
55 let singleton_struct_expand: proc_macro2::TokenStream = quote! {
56 #[derive(Serialize,Deserialize,Clone,Debug)]
57 pub struct #name {
58 pub last_modify:u64,
59 #(
60 pub #field_names: #field_types,
61 )*
62 }
63 impl #name{
64 pub fn new( #( #field_names: #field_types ),*) -> Self {
65 let now_idx = struct_to_json_db::unique_id();
66 Self {
67 last_modify: now_idx.1,
68 #( #field_names, )*
69 }
70 }
71 pub fn get_path()->String{
72 struct_to_json_db::get_struct_json_path()+stringify!(#name)+".json"
73 }
74
75 pub fn save(&mut self){
76 let file_path = Self::get_path();
77 let now_idx = struct_to_json_db::unique_id();
78 self.last_modify = now_idx.1;
79 Self::set_data_string(&file_path, serde_json::to_string(self).unwrap());
80 }
81 pub fn load()->Self{
82 let file_path = Self::get_path();
83 let db_string = Self::get_data_string(&file_path);
84 if let Some(data) = serde_json::from_str(&db_string).ok() {
85 return data;
86 }else{
87 return Self::default();
88 }
89 }
90 pub fn set_data_string(file_path:&str,db_string:String){
91 if #encript_name != ""{
92 match std::env::var(#encript_name) {
93 Ok(encript) => {
94 struct_to_json_db::write_string_to_txt_encript(file_path, db_string,&encript);
95 }
96 Err(e) => {
97 struct_to_json_db::write_string_to_txt(file_path, db_string);
98 }
99 }
100 }else{
101 struct_to_json_db::write_string_to_txt(file_path, db_string);
102 }
103 }
104 pub fn get_data_string(file_path:&str)->String{
105 if #encript_name != ""{
106 match std::env::var(#encript_name) {
107 Ok(encript) => {
108 struct_to_json_db::read_string_from_txt_encript(&file_path,&encript)
109 }
110 Err(e) => {
111 struct_to_json_db::read_string_from_txt(&file_path)
112 }
113 }
114 }else{
115 struct_to_json_db::read_string_from_txt(&file_path)
116 }
117 }
118 }
119 };
120 let complex_struct_expand: proc_macro2::TokenStream = quote! {
121 #[derive(Serialize,Deserialize,Clone,Debug)]
122 pub struct #name_behalf{
123 pub idx: u64,
124 #(
125 pub #unique_field: #unique_field_types,
126 )*
127 }
128 impl #name_behalf{
129 pub fn new( idx:u64, #( #unique_field: #unique_field_types ),*) -> Self {
130 Self {
132 idx: idx,
133 #( #unique_field,)*
134 }
135 }
136 pub fn idx(&self)->u64{
137 self.idx
138 }
139 pub fn get_path()->String{
140 struct_to_json_db::get_struct_json_path()+stringify!(#name)+".json"
141 }
142 pub fn get_unique_hash(&self) -> String {
143 if #unique_field_len > 0 {
144 let mut ukey = String::new();
145 #( ukey += &self.#unique_field.to_string(); )*
146 struct_to_json_db::string_to_unique_id(&ukey)
147 } else {
148 self.idx.to_string()
149 }
150 }
151 pub fn get_by_id(id: u64) -> Option<Self> {
152 let db = Self::get_all();
153 db.get(&id).cloned()
154 }
155 pub fn get_by_ids(ids: &Vec<u64>) -> Vec<Self> {
156 let db = Self::get_all();
157 ids.iter().filter_map(|id| db.get(&id).cloned()).collect()
158 }
159 pub fn remove_by_id(id: u64){
160 let file_path = Self::get_path();
161 let mut db = Self::get_all();
162 db.remove(&id);
163 let db_string = serde_json::to_string(&db).unwrap();
164 Self::set_data_string(&file_path, db_string);
165 }
166 pub fn remove_by_ids(ids: &Vec<u64>){
167 let file_path = Self::get_path();
168 let mut db = Self::get_all();
169 for id in ids{
170 db.remove(&id);
171 }
172 let db_string = serde_json::to_string(&db).unwrap();
173 Self::set_data_string(&file_path, db_string);
174 }
175 pub fn get_all()->std::collections::HashMap<u64,Self>{
176 let file_path = Self::get_path();
177 let db_string = Self::get_data_string(&file_path);
178 let db:std::collections::HashMap<u64,Self> = serde_json::from_str(&db_string).unwrap_or_default();
179 db
180 }
181 pub fn load(&self)->Option< #name >{
182 #name ::get_by_id(self.idx)
183 }
184 pub fn clear(){
185 let file_path = Self::get_path();
186 struct_to_json_db::write_string_to_txt(&file_path, "".to_owned());
187 }
188 pub fn save(&self){
189 let mut db = Self::get_all();
190 db.insert(self.idx, self.clone());
191 Self::save_all(&db);
192 }
193
194 pub fn save_vec(v:Vec<Self>){
195 let file_path = Self::get_path();
196 let mut db = Self::get_all();
197 for i in v{
198 db.insert(i.idx, i);
199 }
200 let db_string = serde_json::to_string(&db).unwrap();
201 Self::set_data_string(&file_path, db_string);
202 }
203 pub fn save_all(db:&std::collections::HashMap<u64,Self>){
204 let file_path = Self::get_path();
205 let db_string = serde_json::to_string(db).unwrap();
206 Self::set_data_string(&file_path, db_string);
207 }
208 pub fn remove(&self){
209 Self::remove_by_id(self.idx);
210 }
211 pub fn set_data_string(file_path:&str,db_string:String){
212 if #encript_name != ""{
213 match std::env::var(#encript_name) {
214 Ok(encript) => {
215 struct_to_json_db::write_string_to_txt_encript(file_path, db_string,&encript);
216 }
217 Err(e) => {
218 struct_to_json_db::write_string_to_txt(file_path, db_string);
219 }
220 }
221 }else{
222 struct_to_json_db::write_string_to_txt(file_path, db_string);
223 }
224 }
225 pub fn get_data_string(file_path:&str)->String{
226 if #encript_name != ""{
227 match std::env::var(#encript_name) {
228 Ok(encript) => {
229 struct_to_json_db::read_string_from_txt_encript(&file_path,&encript)
230 }
231 Err(e) => {
232 struct_to_json_db::read_string_from_txt(&file_path)
233 }
234 }
235 }else{
236 struct_to_json_db::read_string_from_txt(&file_path)
237 }
238 }
239 }
240
241 #[derive(Serialize,Deserialize,Clone,Debug)]
242 pub struct #name {
243 pub idx: u64,
244 pub created_at:u64,
245 #(
246 pub #field_names: #field_types,
247 )*
248 }
249 impl #name {
250 pub fn new( #( #field_names: #field_types ),*) -> Self {
251 let now_idx = struct_to_json_db::unique_id();
252 Self {
253 idx: now_idx.0^now_idx.1,
254 created_at: now_idx.1,
255 #( #field_names, )*
256 }
257 }
258 pub fn idx(&self)->u64{
259 self.idx
260 }
261 pub fn get_path()->String{
262 struct_to_json_db::get_struct_json_path()+stringify!(#name)
263 }
264 pub fn get_unique_hash(&self) -> String {
265 if #unique_field_len > 0 {
266 let mut ukey = String::new();
267 #( ukey += &self.#unique_field.to_string(); )*
268 struct_to_json_db::string_to_unique_id(&ukey)
269 } else {
270 self.idx.to_string()
271 }
272 }
273 pub fn get_by_id(id: u64) -> Option<Self> {
274 let file_path = format!("{}/{}.json",Self::get_path(),id.to_string());
275 let db_string = Self::get_data_string(&file_path);
276 serde_json::from_str(&db_string).ok()
277 }
278 pub fn get_by_ids(ids: &Vec<u64>) -> Vec<Self> {
279 ids.iter().filter_map(|id| Self::get_by_id(id.clone())).collect()
280 }
281 pub fn remove_by_id(id: u64){
282 let file_path = format!("{}/{}.json",Self::get_path(),id.to_string());
283 struct_to_json_db::remove_file_by_path(&file_path);
284 #name_behalf::remove_by_id(id);
285 }
286 pub fn remove_by_ids(ids: &Vec<u64>){
287 ids.iter().for_each(|id|{
288 Self::remove_by_id(id.clone());
289 });
290 }
291 pub fn get_all()->std::collections::HashMap<u64,#name_behalf>{
292 let db = #name_behalf::get_all();
293 db
294 }
295
296 pub fn clear(){
297 let file_path = Self::get_path()+".json";
298 struct_to_json_db::write_string_to_txt(&file_path, "".to_owned());
299 struct_to_json_db::remove_all_files_by_path(&Self::get_path());
300 }
301 pub fn update(&mut self){
302 let mut exist_item:Vec<u64> = vec![];
303 let db = #name_behalf::get_all();
304 if #unique_field_len > 0 {
305 exist_item = db.values().filter(|item| {
306 #( self. #unique_field == item. #unique_field && )* true
307 }).map(|item| item.idx).collect();
308 }
309 if exist_item.len() > 0{
310 self.idx = exist_item[0];
311 let file_path = format!("{}/{}.json",Self::get_path(),exist_item[0].to_string());
312 Self::set_data_string(&file_path, serde_json::to_string(self).unwrap());
313 }
314 }
315 pub fn save_or_update(&mut self){
316 let idx = self.save();
317 if idx.is_none(){
318 self.update();
319 }
320 }
321 pub fn save(&self)->Option<u64>{
322 let item = Self::get_by_id(self.idx);
323 let bh = self.behalf();
324 let folder_path = Self::get_path();
325 struct_to_json_db::make_folder_if_not_exist(&folder_path);
326
327 if item.is_none() {
328 let mut exists = false;
329 let mut db = #name_behalf::get_all();
330 if #unique_field_len > 0 {
331 exists = db.values().any(|item| {
332 #( self. #unique_field == item. #unique_field && )* true
333 });
334 }
335 if exists{
336 return None;
337 }else{
338 let file_path = format!("{}/{}.json",Self::get_path(),self.idx.to_string());
339 Self::set_data_string(&file_path, serde_json::to_string(self).unwrap());
340 bh.save();
341 return Some(self.idx);
342 }
343 }else{
344 let file_path = format!("{}/{}.json",Self::get_path(),self.idx.to_string());
345 Self::set_data_string(&file_path, serde_json::to_string(self).unwrap());
346 bh.save();
347 return Some(self.idx);
348 }
349 }
350 #(
351 pub fn #unique_field(value: &#unique_field_types)-> Option<Self>{
352 let db = #name::get_all();
353 let rel:Vec<Self> = db.values().filter(|item| &item. #unique_field == value).map(|item| Self::get_by_id(item.idx).unwrap()).collect();
354 if rel.len()>0{
355 return Some(rel[0].clone());
356 }
357 None
358 }
359 )*
360 pub fn behalf(&self)->#name_behalf{
361 #name_behalf::new(self.idx #(, self. #unique_field .clone() )*)
362 }
363 pub fn save_vec(v:Vec<Self>){
364 v.into_iter().for_each(|item|{
365 item.save();
366 });
367 }
368 pub fn save_all(db:&std::collections::HashMap<u64,Self>){
369 db.iter().for_each(|(idx, item)| {
370 item.save();
371 });
372 }
373 pub fn remove(&self){
374 Self::remove_by_id(self.idx);
375 }
376 pub fn set_data_string(file_path:&str,db_string:String){
377 if #encript_name != ""{
378 match std::env::var(#encript_name) {
379 Ok(encript) => {
380 struct_to_json_db::write_string_to_txt_encript(file_path, db_string,&encript);
381 }
382 Err(e) => {
383 struct_to_json_db::write_string_to_txt(file_path, db_string);
384 }
385 }
386 }else{
387 struct_to_json_db::write_string_to_txt(file_path, db_string);
388 }
389 }
390 pub fn get_data_string(file_path:&str)->String{
391 if #encript_name != ""{
392 match std::env::var(#encript_name) {
393 Ok(encript) => {
394 struct_to_json_db::read_string_from_txt_encript(&file_path,&encript)
395 }
396 Err(e) => {
397 struct_to_json_db::read_string_from_txt(&file_path)
398 }
399 }
400 }else{
401 struct_to_json_db::read_string_from_txt(&file_path)
402 }
403 }
404 }
405
406 };
407
408 let default_struct_expand: proc_macro2::TokenStream = quote! {
409 #[derive(Serialize,Deserialize,Clone,Debug)]
410 pub struct #name {
411 pub idx: u64,
412 pub created_at:u64,
413 #(
414 pub #field_names: #field_types,
415 )*
416 }
417 impl #name {
418 pub fn new( #( #field_names: #field_types ),*) -> Self {
419 let now_idx = struct_to_json_db::unique_id();
420 Self {
421 idx: now_idx.0^now_idx.1,
422 created_at: now_idx.1,
423 #( #field_names, )*
424 }
425 }
426 pub fn idx(&self)->u64{
427 self.idx
428 }
429 pub fn get_path()->String{
430 struct_to_json_db::get_struct_json_path()+stringify!(#name)+".json"
431 }
432 pub fn get_unique_hash(&self) -> String {
433 if #unique_field_len > 0 {
434 let mut ukey = String::new();
435 #( ukey += &self.#unique_field.to_string(); )*
436 struct_to_json_db::string_to_unique_id(&ukey)
437 } else {
438 self.idx.to_string()
439 }
440 }
441 pub fn get_by_id(id: u64) -> Option<Self> {
442 let db = Self::get_all();
443 db.get(&id).cloned()
444 }
445 pub fn get_by_ids(ids: &Vec<u64>) -> Vec<Self> {
446 let db = Self::get_all();
447 ids.iter().filter_map(|id| db.get(&id).cloned()).collect()
448 }
449 pub fn remove_by_id(id: u64){
450 let file_path = Self::get_path();
451 let mut db = Self::get_all();
452 db.remove(&id);
453 let db_string = serde_json::to_string(&db).unwrap();
454 Self::set_data_string(&file_path, db_string);
455 }
456 pub fn remove_by_ids(ids: &Vec<u64>){
457 let file_path = Self::get_path();
458 let mut db = Self::get_all();
459 for id in ids{
460 db.remove(&id);
461 }
462 let db_string = serde_json::to_string(&db).unwrap();
463 Self::set_data_string(&file_path, db_string);
464 }
465 pub fn get_all()->std::collections::HashMap<u64,Self>{
466 let file_path = Self::get_path();
467 let db_string = Self::get_data_string(&file_path);
468 let db:std::collections::HashMap<u64,Self> = serde_json::from_str(&db_string).unwrap_or_default();
469 db
470 }
471 #(
472 pub fn #unique_field(value: &#unique_field_types)-> Option<Self>{
473 let db = #name::get_all();
474 let rel:Vec<Self> = db.values().filter(|item| &item. #unique_field == value).map(|item| Self::get_by_id(item.idx).unwrap()).collect();
475 if rel.len()>0{
476 return Some(rel[0].clone());
477 }
478 None
479 }
480 )*
481 pub fn clear(){
482 let file_path = Self::get_path();
483 struct_to_json_db::write_string_to_txt(&file_path, "".to_owned());
484 }
485 pub fn update(&mut self){
486 let mut exist_item:Vec<u64> = vec![];
487 let mut db = Self::get_all();
488 if #unique_field_len > 0 {
489 exist_item = db.values().filter(|item| {
490 #( self. #unique_field == item. #unique_field && )* true
491 }).map(|item| item.idx).collect();
492 }
493 if exist_item.len() > 0{
494 self.idx = exist_item[0];
495 db.insert(self.idx, self.clone());
496 Self::save_all(&db);
497 }
498 }
499 pub fn save_or_update(&mut self){
500 let idx = self.save();
501 if idx.is_none(){
502 self.update();
503 }
504 }
505 pub fn save(&self)->Option<u64>{
506 let mut db = Self::get_all();
507 let idx = self.idx;
508 let item_idx:u64 = db.get(&idx).map(|item|item.idx).unwrap_or(0);
509 let mut exists = false;
510 if idx == item_idx{
511 db.insert(self.idx, self.clone());
513 Self::save_all(&db);
514 Some(idx)
515 }else{
516 if #unique_field_len > 0 {
518 exists = db.values().any(|item| {
519 #( self. #unique_field == item. #unique_field && )* true
520 });
521 }
522 if exists{
523 None
524 }else{
525 db.insert(self.idx, self.clone());
526 Self::save_all(&db);
527 Some(idx)
528 }
529 }
530 }
531 pub fn save_vec(v:Vec<Self>){
532 let file_path = Self::get_path();
533 let mut db = Self::get_all();
534 for i in v{
535 db.insert(i.idx, i);
536 }
537 let db_string = serde_json::to_string(&db).unwrap();
538 Self::set_data_string(&file_path, db_string);
539 }
540 pub fn save_all(db:&std::collections::HashMap<u64,Self>){
541 let file_path = Self::get_path();
542 let db_string = serde_json::to_string(db).unwrap();
543 Self::set_data_string(&file_path, db_string);
544 }
545 pub fn remove(&self){
546 Self::remove_by_id(self.idx);
547 }
548 pub fn set_data_string(file_path:&str,db_string:String){
549 if #encript_name != ""{
550 match std::env::var(#encript_name) {
551 Ok(encript) => {
552 struct_to_json_db::write_string_to_txt_encript(file_path, db_string,&encript);
553 }
554 Err(e) => {
555 struct_to_json_db::write_string_to_txt(file_path, db_string);
556 }
557 }
558 }else{
559 struct_to_json_db::write_string_to_txt(file_path, db_string);
560 }
561 }
562 pub fn get_data_string(file_path:&str)->String{
563 if #encript_name != ""{
564 match std::env::var(#encript_name) {
565 Ok(encript) => {
566 struct_to_json_db::read_string_from_txt_encript(&file_path,&encript)
567 }
568 Err(e) => {
569 struct_to_json_db::read_string_from_txt(&file_path)
570 }
571 }
572 }else{
573 struct_to_json_db::read_string_from_txt(&file_path)
574 }
575 }
576 }
577
578 };
579 if is_singleton{
580 return TokenStream::from(singleton_struct_expand);
581 }
582 if is_complex {
583 return TokenStream::from(complex_struct_expand);
584 }
585 return TokenStream::from(default_struct_expand);
586
587}
588fn parse_string_to_hashmap(input: &str) -> std::collections::HashMap<String, String> {
589 let re = Regex::new(r#"\s*(\w+)(?:\s*=\s*"([^"]*)")?\s*(?:,|$)"#).unwrap();
591 let mut map = std::collections::HashMap::new();
592 for cap in re.captures_iter(input) {
593 let key = cap[1].to_string();
594 let value = if let Some(value_match) = cap.get(2) {
595 value_match.as_str().to_string()
596 } else {
597 "true".to_string()
598 };
599 map.insert(key, value);
600 }
601 map
602}
603