util.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. use dashmap::{DashMap, DashSet};
  2. use flowy_ast::{Ctxt, TyInfo};
  3. use lazy_static::lazy_static;
  4. use lib_infra::proto_gen::ProtoCache;
  5. use std::fs::File;
  6. use std::io::Read;
  7. use std::sync::atomic::{AtomicBool, Ordering};
  8. use walkdir::WalkDir;
  9. pub fn ident_category(ident: &syn::Ident) -> TypeCategory {
  10. let ident_str = ident.to_string();
  11. category_from_str(ident_str)
  12. }
  13. pub(crate) fn get_member_ident<'a>(ctxt: &Ctxt, member: &'a syn::Member) -> Option<&'a syn::Ident> {
  14. if let syn::Member::Named(ref ident) = member {
  15. Some(ident)
  16. } else {
  17. ctxt.error_spanned_by(member, "Unsupported member, shouldn't be self.0".to_string());
  18. None
  19. }
  20. }
  21. pub fn assert_bracket_ty_is_some(ctxt: &Ctxt, ty_info: &TyInfo) {
  22. if ty_info.bracket_ty_info.is_none() {
  23. ctxt.error_spanned_by(ty_info.ty, "Invalid bracketed type when gen de token steam".to_string());
  24. }
  25. }
  26. lazy_static! {
  27. static ref READ_FLAG: DashSet<String> = DashSet::new();
  28. static ref CACHE_INFO: DashMap<TypeCategory, Vec<String>> = DashMap::new();
  29. static ref IS_LOAD: AtomicBool = AtomicBool::new(false);
  30. }
  31. #[derive(Eq, Hash, PartialEq)]
  32. pub enum TypeCategory {
  33. Array,
  34. Map,
  35. Str,
  36. Protobuf,
  37. Bytes,
  38. Enum,
  39. Opt,
  40. Primitive,
  41. }
  42. // auto generate, do not edit
  43. pub fn category_from_str(type_str: String) -> TypeCategory {
  44. if !IS_LOAD.load(Ordering::SeqCst) {
  45. IS_LOAD.store(true, Ordering::SeqCst);
  46. // Dependents on another crate file is not good, just leave it here.
  47. // Maybe find another way to read the .cache in the future.
  48. let cache_dir = format!("{}/../lib-infra/.cache", env!("CARGO_MANIFEST_DIR"));
  49. for path in WalkDir::new(cache_dir)
  50. .into_iter()
  51. .filter_map(|e| e.ok())
  52. .map(|e| e.path().to_str().unwrap().to_string())
  53. {
  54. match read_file(&path) {
  55. None => {}
  56. Some(s) => {
  57. let cache: ProtoCache = serde_json::from_str(&s).unwrap();
  58. CACHE_INFO
  59. .entry(TypeCategory::Protobuf)
  60. .or_insert(vec![])
  61. .extend(cache.structs);
  62. CACHE_INFO
  63. .entry(TypeCategory::Enum)
  64. .or_insert(vec![])
  65. .extend(cache.enums);
  66. }
  67. }
  68. }
  69. }
  70. if let Some(protobuf) = CACHE_INFO.get(&TypeCategory::Protobuf) {
  71. if protobuf.contains(&type_str) {
  72. return TypeCategory::Protobuf;
  73. }
  74. }
  75. if let Some(protobuf) = CACHE_INFO.get(&TypeCategory::Enum) {
  76. if protobuf.contains(&type_str) {
  77. return TypeCategory::Enum;
  78. }
  79. }
  80. match type_str.as_str() {
  81. "Vec" => TypeCategory::Array,
  82. "HashMap" => TypeCategory::Map,
  83. "u8" => TypeCategory::Bytes,
  84. "String" => TypeCategory::Str,
  85. "Option" => TypeCategory::Opt,
  86. _ => TypeCategory::Primitive,
  87. }
  88. }
  89. fn read_file(path: &str) -> Option<String> {
  90. match File::open(path) {
  91. Ok(mut file) => {
  92. let mut content = String::new();
  93. match file.read_to_string(&mut content) {
  94. Ok(_) => Some(content),
  95. Err(_) => None,
  96. }
  97. }
  98. Err(_) => None,
  99. }
  100. }