util.rs 3.1 KB

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