Przeglądaj źródła

Merge pull request #337 from AppFlowy-IO/auto_gen_dart_event

Auto gen dart event
Nathan.fooo 3 lat temu
rodzic
commit
91b1430e7b
66 zmienionych plików z 583 dodań i 224 usunięć
  1. 0 3
      .github/workflows/rust_lint.yml
  2. 1 1
      .run/dart-event.run.xml
  3. 5 1
      frontend/Makefile
  4. 3 3
      frontend/Makefile.toml
  5. 7 0
      frontend/app_flowy/.vscode/launch.json
  6. 21 0
      frontend/app_flowy/.vscode/tasks.json
  7. 2 1
      frontend/app_flowy/packages/flowy_sdk/.gitignore
  8. 1 2
      frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event.dart
  9. 1 1
      frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart
  10. 11 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/event_map.pb.dart
  11. 24 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/event_map.pbenum.dart
  12. 20 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/event_map.pbjson.dart
  13. 9 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/event_map.pbserver.dart
  14. 1 1
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/protobuf.dart
  15. 2 2
      frontend/rust-lib/dart-ffi/Cargo.toml
  16. 14 2
      frontend/rust-lib/dart-ffi/build.rs
  17. 2 2
      frontend/rust-lib/dart-notify/build.rs
  18. 2 2
      frontend/rust-lib/flowy-error/build.rs
  19. 4 2
      frontend/rust-lib/flowy-folder/build.rs
  20. 1 15
      frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs
  21. 2 2
      frontend/rust-lib/flowy-net/Flowy.toml
  22. 4 2
      frontend/rust-lib/flowy-net/build.rs
  23. 0 9
      frontend/rust-lib/flowy-net/src/event.rs
  24. 19 0
      frontend/rust-lib/flowy-net/src/event_map.rs
  25. 1 2
      frontend/rust-lib/flowy-net/src/lib.rs
  26. 0 10
      frontend/rust-lib/flowy-net/src/module.rs
  27. 3 3
      frontend/rust-lib/flowy-net/src/protobuf/model/event_map.rs
  28. 2 2
      frontend/rust-lib/flowy-net/src/protobuf/model/mod.rs
  29. 0 0
      frontend/rust-lib/flowy-net/src/protobuf/proto/event_map.proto
  30. 1 1
      frontend/rust-lib/flowy-sdk/src/module.rs
  31. 4 2
      frontend/rust-lib/flowy-user/build.rs
  32. 0 27
      frontend/rust-lib/flowy-user/src/event.rs
  33. 7 0
      frontend/scripts/clean.cmd
  34. 10 0
      frontend/scripts/clean.sh
  35. 2 2
      frontend/scripts/makefile/protobuf.toml
  36. 2 2
      shared-lib/flowy-collaboration/build.rs
  37. 1 0
      shared-lib/flowy-derive/src/proto_buf/mod.rs
  38. 2 1
      shared-lib/flowy-derive/src/proto_buf/util.rs
  39. 2 2
      shared-lib/flowy-error-code/build.rs
  40. 2 2
      shared-lib/flowy-folder-data-model/build.rs
  41. 2 2
      shared-lib/flowy-user-data-model/build.rs
  42. 2 1
      shared-lib/lib-infra/Cargo.toml
  43. 165 0
      shared-lib/lib-infra/src/code_gen/dart_event/dart_event.rs
  44. 61 0
      shared-lib/lib-infra/src/code_gen/dart_event/event_template.rs
  45. 45 0
      shared-lib/lib-infra/src/code_gen/dart_event/event_template.tera
  46. 5 0
      shared-lib/lib-infra/src/code_gen/dart_event/mod.rs
  47. 3 3
      shared-lib/lib-infra/src/code_gen/flowy_toml.rs
  48. 17 0
      shared-lib/lib-infra/src/code_gen/mod.rs
  49. 5 5
      shared-lib/lib-infra/src/code_gen/protobuf_file/ast.rs
  50. 26 16
      shared-lib/lib-infra/src/code_gen/protobuf_file/mod.rs
  51. 8 13
      shared-lib/lib-infra/src/code_gen/protobuf_file/proto_gen.rs
  52. 2 2
      shared-lib/lib-infra/src/code_gen/protobuf_file/proto_info.rs
  53. 2 2
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/derive_meta/derive_meta.rs
  54. 0 0
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/derive_meta/derive_meta.tera
  55. 0 0
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/derive_meta/mod.rs
  56. 5 0
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/mod.rs
  57. 0 0
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/enum.tera
  58. 3 3
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/enum_template.rs
  59. 0 0
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/mod.rs
  60. 0 0
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/struct.tera
  61. 2 3
      shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/struct_template.rs
  62. 32 2
      shared-lib/lib-infra/src/code_gen/util.rs
  63. 1 6
      shared-lib/lib-infra/src/lib.rs
  64. 0 10
      shared-lib/lib-infra/src/proto_gen/mod.rs
  65. 0 47
      shared-lib/lib-infra/src/proto_gen/template/mod.rs
  66. 2 2
      shared-lib/lib-ws/build.rs

+ 0 - 3
.github/workflows/rust_lint.yml

@@ -41,9 +41,6 @@ jobs:
         with:
           toolchain: stable
           override: true
-      - name: Install cargo-make
-        run: cargo install --force cargo-make
-        working-directory: frontend
       - run: rustup component add clippy
         working-directory: frontend/rust-lib
       - run: cargo clippy --no-default-features

+ 1 - 1
.run/dart-event.run.xml

@@ -1,6 +1,6 @@
 <component name="ProjectRunConfigurationManager">
   <configuration default="false" name="dart-event" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
-    <option name="command" value="run --manifest-path $PROJECT_DIR$/scripts/flowy-tool/Cargo.toml -- dart-event --rust_source=$PROJECT_DIR$/rust-lib/  --output=$PROJECT_DIR$/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart" />
+    <option name="command" value="run --manifest-path $PROJECT_DIR$/scripts/flowy-tool/Cargo.toml -- dart-event --rust_source=$PROJECT_DIR$/rust-lib/  --output=$PROJECT_DIR$/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event.dart" />
     <option name="workingDirectory" value="file://$PROJECT_DIR$" />
     <option name="channel" value="DEFAULT" />
     <option name="allFeatures" value="false" />

+ 5 - 1
frontend/Makefile

@@ -1,4 +1,4 @@
-.PHONY: flowy_dev_install
+.PHONY: flowy_dev_install flowy_clean
 
 flowy_dev_install:
 	brew bundle
@@ -8,3 +8,7 @@ flowy_dev_install:
 	cargo make flowy_dev
 
 
+flowy_clean:
+	sh ./scripts/clean.sh
+
+

+ 3 - 3
frontend/Makefile.toml

@@ -21,7 +21,7 @@ PRODUCT_NAME = "AppFlowy"
 CRATE_TYPE = "staticlib"
 SDK_EXT = "a"
 APP_ENVIRONMENT = "local"
-FLUTTER_FLOWY_SDK_PATH="app_flowy/packages/flowy_sdk/lib/protobuf"
+FLUTTER_FLOWY_SDK_PATH="app_flowy/packages/flowy_sdk"
 PROTOBUF_DERIVE_CACHE="../shared-lib/flowy-derive/src/derive_cache/derive_cache.rs"
 
 [env.development-mac]
@@ -158,8 +158,8 @@ script_runner = "@duckscript"
 condition = { env_set = [ "FLUTTER_FLOWY_SDK_PATH"] }
 script = [
     """
-      cd ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/../shared-lib/error-code
-      cargo build -vv
+      cd ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/flowy-net
+      cargo build -vv --features=dart
       """,
 ]
 script_runner = "@shell"

+ 7 - 0
frontend/app_flowy/.vscode/launch.json

@@ -40,5 +40,12 @@
             "preLaunchTask": "Generate Language Files",
             "cwd": "${workspaceRoot}"
         },
+        {
+            "name": "Clean",
+            "request": "launch",
+            "type": "dart",
+            "preLaunchTask": "Clean",
+            "cwd": "${workspaceRoot}"
+        }
     ]
 }

+ 21 - 0
frontend/app_flowy/.vscode/tasks.json

@@ -70,6 +70,27 @@
 			"options": {
 				"cwd": "${workspaceFolder}/../"
 			},
+		},
+		{
+			"label": "Clean FlowySDK",
+			"type": "shell",
+			"command": "sh ./scripts/clean.sh",
+			"windows": {
+				"options": {
+					"shell": {
+						"executable": "cmd.exe",
+						"args": [
+							"/d",
+							"/c",
+							".\\scripts\\clean.cmd"
+						]
+					}
+				}
+			},
+			"group": "build",
+			"options": {
+				"cwd": "${workspaceFolder}/../"
+			},
 		}
 	]
 }

+ 2 - 1
frontend/app_flowy/packages/flowy_sdk/.gitignore

@@ -77,4 +77,5 @@ build/
 **/*.a
 **/*.lib
 **/*.dll
-**/*.so
+**/*.so
+# lib/**/dart_event.dart

+ 1 - 2
frontend/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart → frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event.dart

@@ -1,6 +1,5 @@
 
-
-/// Auto gen code from rust ast, do not edit
+/// Auto generate. Do not edit
 part of 'dispatch.dart';
 class FolderEventCreateWorkspace {
      CreateWorkspaceRequest request;

+ 1 - 1
frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart

@@ -27,7 +27,7 @@ import 'package:protobuf/protobuf.dart';
 import 'dart:convert' show utf8;
 import 'error.dart';
 
-part 'code_gen.dart';
+part 'dart_event.dart';
 
 enum FFIException {
   RequestIsEmpty,

+ 11 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/event_map.pb.dart

@@ -0,0 +1,11 @@
+///
+//  Generated code. Do not modify.
+//  source: event_map.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+import 'dart:core' as $core;
+
+export 'event_map.pbenum.dart';
+

+ 24 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/event_map.pbenum.dart

@@ -0,0 +1,24 @@
+///
+//  Generated code. Do not modify.
+//  source: event_map.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+// ignore_for_file: UNDEFINED_SHOWN_NAME
+import 'dart:core' as $core;
+import 'package:protobuf/protobuf.dart' as $pb;
+
+class NetworkEvent extends $pb.ProtobufEnum {
+  static const NetworkEvent UpdateNetworkType = NetworkEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateNetworkType');
+
+  static const $core.List<NetworkEvent> values = <NetworkEvent> [
+    UpdateNetworkType,
+  ];
+
+  static final $core.Map<$core.int, NetworkEvent> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static NetworkEvent? valueOf($core.int value) => _byValue[value];
+
+  const NetworkEvent._($core.int v, $core.String n) : super(v, n);
+}
+

+ 20 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/event_map.pbjson.dart

@@ -0,0 +1,20 @@
+///
+//  Generated code. Do not modify.
+//  source: event_map.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+import 'dart:core' as $core;
+import 'dart:convert' as $convert;
+import 'dart:typed_data' as $typed_data;
+@$core.Deprecated('Use networkEventDescriptor instead')
+const NetworkEvent$json = const {
+  '1': 'NetworkEvent',
+  '2': const [
+    const {'1': 'UpdateNetworkType', '2': 0},
+  ],
+};
+
+/// Descriptor for `NetworkEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List networkEventDescriptor = $convert.base64Decode('CgxOZXR3b3JrRXZlbnQSFQoRVXBkYXRlTmV0d29ya1R5cGUQAA==');

+ 9 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/event_map.pbserver.dart

@@ -0,0 +1,9 @@
+///
+//  Generated code. Do not modify.
+//  source: event_map.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+export 'event_map.pb.dart';
+

+ 1 - 1
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-net/protobuf.dart

@@ -1,3 +1,3 @@
 // Auto-generated, do not edit 
 export './network_state.pb.dart';
-export './event.pb.dart';
+export './event_map.pb.dart';

+ 2 - 2
frontend/rust-lib/dart-ffi/Cargo.toml

@@ -29,8 +29,8 @@ dart-notify = {path = "../dart-notify" }
 flowy-derive = {path = "../../../shared-lib/flowy-derive" }
 
 [features]
-default = ["flowy-sdk/dart"]
-flutter = ["dart-notify/dart"]
+default = ["flowy-sdk/dart", "dart-notify/dart", "flutter"]
+flutter = []
 http_server = ["flowy-sdk/http_server", "flowy-sdk/use_bunyan"]
 #use_serde = ["bincode"]
 #use_protobuf= ["protobuf"]

+ 14 - 2
frontend/rust-lib/dart-ffi/build.rs

@@ -1,5 +1,17 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
+use lib_infra::code_gen::dart_event;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    #[cfg(feature = "flutter")]
+    copy_dart_event_files();
+}
+
+#[cfg(feature = "flutter")]
+fn copy_dart_event_files() {
+    let workspace_dir = std::env::var("CARGO_MAKE_WORKING_DIRECTORY").unwrap();
+    let flutter_sdk_path = std::env::var("FLUTTER_FLOWY_SDK_PATH").unwrap();
+    let output_file = format!("{}/{}/lib/dispatch/dart_event.dart", workspace_dir, flutter_sdk_path);
+    println!("cargo:rerun-if-changed={}", output_file);
+    dart_event::write_dart_event_file(&output_file);
 }

+ 2 - 2
frontend/rust-lib/dart-notify/build.rs

@@ -1,5 +1,5 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
 }

+ 2 - 2
frontend/rust-lib/flowy-error/build.rs

@@ -1,5 +1,5 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files("flowy-error", "./src/protobuf/proto");
+    code_gen::protobuf_file::gen("flowy-error", "./src/protobuf/proto");
 }

+ 4 - 2
frontend/rust-lib/flowy-folder/build.rs

@@ -1,5 +1,7 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    let crate_name = env!("CARGO_PKG_NAME");
+    code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
+    code_gen::dart_event::gen(crate_name);
 }

+ 1 - 15
frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs

@@ -7,21 +7,7 @@ use flowy_test::{event_builder::*, FlowySDKTest};
 async fn workspace_read_all() {
     let mut test = FolderTest::new().await;
     test.run_scripts(vec![ReadAllWorkspaces]).await;
-    // The first workspace will be the default workspace
-    // The second workspace will be created by FolderTest
-    assert_eq!(test.all_workspace.len(), 2);
-
-    let new_name = "My new workspace".to_owned();
-    test.run_scripts(vec![
-        CreateWorkspace {
-            name: new_name.clone(),
-            desc: "Daily routines".to_owned(),
-        },
-        ReadAllWorkspaces,
-    ])
-    .await;
-    assert_eq!(test.all_workspace.len(), 3);
-    assert_eq!(test.all_workspace[2].name, new_name);
+    assert!(!test.all_workspace.is_empty());
 }
 
 #[tokio::test]

+ 2 - 2
frontend/rust-lib/flowy-net/Flowy.toml

@@ -1,2 +1,2 @@
-proto_crates = ["src/event.rs", "src/entities"]
-event_files = ["src/event.rs"]
+proto_crates = ["src/event_map.rs", "src/entities"]
+event_files = ["src/event_map.rs"]

+ 4 - 2
frontend/rust-lib/flowy-net/build.rs

@@ -1,5 +1,7 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    let crate_name = env!("CARGO_PKG_NAME");
+    code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
+    code_gen::dart_event::gen(crate_name);
 }

+ 0 - 9
frontend/rust-lib/flowy-net/src/event.rs

@@ -1,9 +0,0 @@
-use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
-use strum_macros::Display;
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
-#[event_err = "FlowyError"]
-pub enum NetworkEvent {
-    #[event(input = "NetworkState")]
-    UpdateNetworkType = 0,
-}

+ 19 - 0
frontend/rust-lib/flowy-net/src/event_map.rs

@@ -0,0 +1,19 @@
+use crate::{handlers::*, ws::connection::FlowyWebSocketConnect};
+use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
+use lib_dispatch::prelude::*;
+use std::sync::Arc;
+use strum_macros::Display;
+
+pub fn create(ws_conn: Arc<FlowyWebSocketConnect>) -> Module {
+    Module::new()
+        .name("Flowy-Network")
+        .data(ws_conn)
+        .event(NetworkEvent::UpdateNetworkType, update_network_ty)
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
+#[event_err = "FlowyError"]
+pub enum NetworkEvent {
+    #[event(input = "NetworkState")]
+    UpdateNetworkType = 0,
+}

+ 1 - 2
frontend/rust-lib/flowy-net/src/lib.rs

@@ -1,10 +1,9 @@
 mod configuration;
 pub mod entities;
-mod event;
+pub mod event_map;
 mod handlers;
 pub mod http_server;
 pub mod local_server;
-pub mod module;
 pub mod protobuf;
 mod request;
 pub mod ws;

+ 0 - 10
frontend/rust-lib/flowy-net/src/module.rs

@@ -1,10 +0,0 @@
-use crate::{event::NetworkEvent, handlers::*, ws::connection::FlowyWebSocketConnect};
-use lib_dispatch::prelude::*;
-use std::sync::Arc;
-
-pub fn create(ws_conn: Arc<FlowyWebSocketConnect>) -> Module {
-    Module::new()
-        .name("Flowy-Network")
-        .data(ws_conn)
-        .event(NetworkEvent::UpdateNetworkType, update_network_ty)
-}

+ 3 - 3
frontend/rust-lib/flowy-net/src/protobuf/model/event.rs → frontend/rust-lib/flowy-net/src/protobuf/model/event_map.rs

@@ -17,7 +17,7 @@
 #![allow(trivial_casts)]
 #![allow(unused_imports)]
 #![allow(unused_results)]
-//! Generated file from `event.proto`
+//! Generated file from `event_map.proto`
 
 /// Generated files are compatible only with the same version
 /// of protobuf runtime.
@@ -71,8 +71,8 @@ impl ::protobuf::reflect::ProtobufValue for NetworkEvent {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x0bevent.proto*%\n\x0cNetworkEvent\x12\x15\n\x11UpdateNetworkType\x10\
-    \0b\x06proto3\
+    \n\x0fevent_map.proto*%\n\x0cNetworkEvent\x12\x15\n\x11UpdateNetworkType\
+    \x10\0b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 2 - 2
frontend/rust-lib/flowy-net/src/protobuf/model/mod.rs

@@ -4,5 +4,5 @@
 mod network_state;
 pub use network_state::*;
 
-mod event;
-pub use event::*;
+mod event_map;
+pub use event_map::*;

+ 0 - 0
frontend/rust-lib/flowy-net/src/protobuf/proto/event.proto → frontend/rust-lib/flowy-net/src/protobuf/proto/event_map.proto


+ 1 - 1
frontend/rust-lib/flowy-sdk/src/module.rs

@@ -24,5 +24,5 @@ fn mk_folder_module(core: Arc<FolderManager>) -> Module {
 }
 
 fn mk_network_module(ws_conn: Arc<FlowyWebSocketConnect>) -> Module {
-    flowy_net::module::create(ws_conn)
+    flowy_net::event_map::create(ws_conn)
 }

+ 4 - 2
frontend/rust-lib/flowy-user/build.rs

@@ -1,5 +1,7 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    let crate_name = env!("CARGO_PKG_NAME");
+    code_gen::protobuf_file::gen(crate_name, "./src/protobuf/proto");
+    code_gen::dart_event::gen(crate_name);
 }

+ 0 - 27
frontend/rust-lib/flowy-user/src/event.rs

@@ -1,27 +0,0 @@
-use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
-use strum_macros::Display;
-
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
-#[event_err = "FlowyError"]
-pub enum UserEvent {
-    #[event()]
-    InitUser = 0,
-
-    #[event(input = "SignInRequest", output = "UserProfile")]
-    SignIn = 1,
-
-    #[event(input = "SignUpRequest", output = "UserProfile")]
-    SignUp = 2,
-
-    #[event(passthrough)]
-    SignOut = 3,
-
-    #[event(input = "UpdateUserRequest")]
-    UpdateUser = 4,
-
-    #[event(output = "UserProfile")]
-    GetUserProfile = 5,
-
-    #[event(output = "UserProfile")]
-    CheckUser = 6,
-}

+ 7 - 0
frontend/scripts/clean.cmd

@@ -0,0 +1,7 @@
+cd rust-lib
+cargo clean
+
+cd ../../shared-lib
+cargo clean
+
+rmdir /s/q lib-infra/.cache

+ 10 - 0
frontend/scripts/clean.sh

@@ -0,0 +1,10 @@
+#!/bin/sh
+#!/usr/bin/env fish
+
+cd rust-lib
+cargo clean
+
+cd ../../shared-lib
+cargo clean
+
+rm -rf lib-infra/.cache

+ 2 - 2
frontend/scripts/makefile/protobuf.toml

@@ -107,7 +107,7 @@ script = [
     flutter_lib=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/packages
 
     rust_source=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/
-    output=${flutter_lib}/flowy_sdk/lib/dispatch/code_gen.dart
+    output=${flutter_lib}/flowy_sdk/lib/dispatch/dart_event.dart
 
     cargo run \
      --manifest-path ${flowy_tool} dart-event \
@@ -124,7 +124,7 @@ script = [
     flutter_lib=set ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/packages
 
     rust_source=set ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/
-    output=set ${flutter_lib}/flowy_sdk/lib/dispatch/code_gen.dart
+    output=set ${flutter_lib}/flowy_sdk/lib/dispatch/dart_event.dart
 
     exec cmd.exe /c cargo run \
      --manifest-path ${flowy_tool} dart-event \

+ 2 - 2
shared-lib/flowy-collaboration/build.rs

@@ -1,5 +1,5 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
 }

+ 1 - 0
shared-lib/flowy-derive/src/proto_buf/mod.rs

@@ -8,6 +8,7 @@ use crate::proto_buf::{
 };
 use flowy_ast::*;
 use proc_macro2::TokenStream;
+use std::default::Default;
 
 pub fn expand_derive(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
     let ctxt = Ctxt::new();

+ 2 - 1
shared-lib/flowy-derive/src/proto_buf/util.rs

@@ -1,7 +1,7 @@
 use dashmap::{DashMap, DashSet};
 use flowy_ast::{Ctxt, TyInfo};
 use lazy_static::lazy_static;
-use lib_infra::proto_gen::ProtoCache;
+use lib_infra::code_gen::ProtoCache;
 use std::fs::File;
 use std::io::Read;
 use std::sync::atomic::{AtomicBool, Ordering};
@@ -54,6 +54,7 @@ pub fn category_from_str(type_str: String) -> TypeCategory {
         for path in WalkDir::new(cache_dir)
             .into_iter()
             .filter_map(|e| e.ok())
+            .filter(|e| e.path().file_stem().unwrap().to_str().unwrap() == "proto_cache")
             .map(|e| e.path().to_str().unwrap().to_string())
         {
             match read_file(&path) {

+ 2 - 2
shared-lib/flowy-error-code/build.rs

@@ -1,5 +1,5 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
 }

+ 2 - 2
shared-lib/flowy-folder-data-model/build.rs

@@ -1,5 +1,5 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
 }

+ 2 - 2
shared-lib/flowy-user-data-model/build.rs

@@ -1,5 +1,5 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
 }

+ 2 - 1
shared-lib/lib-infra/Cargo.toml

@@ -48,4 +48,5 @@ proto_gen = [
     "toml"
 ]
 pb_gen = ["cmd_lib", "protoc-rust", "walkdir", "protoc-bin-vendored",]
-dart = ["proto_gen"]
+dart_event = ["walkdir", "flowy-ast", "tera", "syn"]
+dart = ["proto_gen", "dart_event"]

+ 165 - 0
shared-lib/lib-infra/src/code_gen/dart_event/dart_event.rs

@@ -0,0 +1,165 @@
+use super::event_template::*;
+use crate::code_gen::flowy_toml::{parse_crate_config_from, CrateConfig};
+use crate::code_gen::util::{cache_dir, is_crate_dir, is_hidden, read_file};
+use flowy_ast::{event_ast::*, *};
+use std::fs::File;
+use std::io::Write;
+use syn::Item;
+use walkdir::WalkDir;
+
+pub fn gen(crate_name: &str) {
+    let crate_path = std::fs::canonicalize(".").unwrap().as_path().display().to_string();
+    let event_crates = parse_dart_event_files(vec![crate_path]);
+    let event_ast = event_crates.iter().map(parse_event_crate).flatten().collect::<Vec<_>>();
+
+    let event_render_ctx = ast_to_event_render_ctx(event_ast.as_ref());
+    let mut render_result = String::new();
+    for (index, render_ctx) in event_render_ctx.into_iter().enumerate() {
+        let mut event_template = EventTemplate::new();
+
+        if let Some(content) = event_template.render(render_ctx, index) {
+            render_result.push_str(content.as_ref())
+        }
+    }
+
+    let cache_dir = format!("{}/{}", cache_dir(), crate_name);
+    let dart_event_file_path = format!("{}/dart_event.dart", cache_dir);
+
+    match std::fs::OpenOptions::new()
+        .create(true)
+        .write(true)
+        .append(false)
+        .truncate(true)
+        .open(&dart_event_file_path)
+    {
+        Ok(ref mut file) => {
+            file.write_all(render_result.as_bytes()).unwrap();
+            File::flush(file).unwrap();
+        }
+        Err(err) => {
+            panic!("Failed to open file: {}, {:?}", dart_event_file_path, err);
+        }
+    }
+}
+
+const DART_IMPORTED: &str = r#"
+/// Auto generate. Do not edit
+part of 'dispatch.dart';
+"#;
+
+pub fn write_dart_event_file(file_path: &str) {
+    let cache_dir = cache_dir();
+    let mut content = DART_IMPORTED.to_owned();
+    for path in WalkDir::new(cache_dir)
+        .into_iter()
+        .filter_map(|e| e.ok())
+        .filter(|e| e.path().file_stem().unwrap().to_str().unwrap() == "dart_event")
+        .map(|e| e.path().to_str().unwrap().to_string())
+    {
+        let file_content = read_file(path.as_ref()).unwrap();
+        content.push_str(&file_content);
+    }
+
+    match std::fs::OpenOptions::new()
+        .create(true)
+        .write(true)
+        .append(false)
+        .truncate(true)
+        .open(&file_path)
+    {
+        Ok(ref mut file) => {
+            file.write_all(content.as_bytes()).unwrap();
+            File::flush(file).unwrap();
+        }
+        Err(err) => {
+            panic!("Failed to write dart event file: {}", err);
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct DartEventCrate {
+    crate_path: String,
+    event_files: Vec<String>,
+}
+
+impl DartEventCrate {
+    pub fn from_config(config: &CrateConfig) -> Self {
+        DartEventCrate {
+            crate_path: config.crate_path.clone(),
+            event_files: config.flowy_config.event_files.clone(),
+        }
+    }
+}
+
+pub fn parse_dart_event_files(crate_paths: Vec<String>) -> Vec<DartEventCrate> {
+    let mut dart_event_crates: Vec<DartEventCrate> = vec![];
+    crate_paths.iter().for_each(|path| {
+        let crates = WalkDir::new(path)
+            .into_iter()
+            .filter_entry(|e| !is_hidden(e))
+            .filter_map(|e| e.ok())
+            .filter(is_crate_dir)
+            .flat_map(|e| parse_crate_config_from(&e))
+            .map(|crate_config| DartEventCrate::from_config(&crate_config))
+            .collect::<Vec<DartEventCrate>>();
+        dart_event_crates.extend(crates);
+    });
+    dart_event_crates
+}
+
+pub fn parse_event_crate(event_crate: &DartEventCrate) -> Vec<EventASTContext> {
+    event_crate
+        .event_files
+        .iter()
+        .map(|event_file| {
+            let file_path = format!("{}/{}", event_crate.crate_path, event_file);
+            let file_content = read_file(file_path.as_ref()).unwrap();
+            let ast = syn::parse_file(file_content.as_ref()).expect("Unable to parse file");
+            ast.items
+                .iter()
+                .map(|item| match item {
+                    Item::Enum(item_enum) => {
+                        let ctxt = Ctxt::new();
+                        let attrs =
+                            flowy_ast::enum_from_ast(&ctxt, &item_enum.ident, &item_enum.variants, &item_enum.attrs);
+                        ctxt.check().unwrap();
+                        attrs
+                            .iter()
+                            .filter(|attr| !attr.attrs.event_attrs.ignore)
+                            .enumerate()
+                            .map(|(_index, attr)| EventASTContext::from(&attr.attrs))
+                            .collect::<Vec<_>>()
+                    }
+                    _ => vec![],
+                })
+                .flatten()
+                .collect::<Vec<_>>()
+        })
+        .flatten()
+        .collect::<Vec<EventASTContext>>()
+}
+
+pub fn ast_to_event_render_ctx(ast: &[EventASTContext]) -> Vec<EventRenderContext> {
+    ast.iter()
+        .map(|event_ast| {
+            let input_deserializer = event_ast
+                .event_input
+                .as_ref()
+                .map(|event_input| event_input.get_ident().unwrap().to_string());
+
+            let output_deserializer = event_ast
+                .event_output
+                .as_ref()
+                .map(|event_output| event_output.get_ident().unwrap().to_string());
+
+            EventRenderContext {
+                input_deserializer,
+                output_deserializer,
+                error_deserializer: event_ast.event_error.clone(),
+                event: event_ast.event.to_string(),
+                event_ty: event_ast.event_ty.to_string(),
+            }
+        })
+        .collect::<Vec<EventRenderContext>>()
+}

+ 61 - 0
shared-lib/lib-infra/src/code_gen/dart_event/event_template.rs

@@ -0,0 +1,61 @@
+use crate::code_gen::util::get_tera;
+use tera::Context;
+
+pub struct EventTemplate {
+    tera_context: Context,
+}
+
+pub struct EventRenderContext {
+    pub input_deserializer: Option<String>,
+    pub output_deserializer: Option<String>,
+    pub error_deserializer: String,
+    pub event: String,
+    pub event_ty: String,
+}
+
+#[allow(dead_code)]
+impl EventTemplate {
+    pub fn new() -> Self {
+        EventTemplate {
+            tera_context: Context::new(),
+        }
+    }
+
+    pub fn render(&mut self, ctx: EventRenderContext, index: usize) -> Option<String> {
+        self.tera_context.insert("index", &index);
+        let dart_class_name = format!("{}{}", ctx.event_ty, ctx.event);
+        let event = format!("{}.{}", ctx.event_ty, ctx.event);
+        self.tera_context.insert("event_class", &dart_class_name);
+        self.tera_context.insert("event", &event);
+
+        self.tera_context.insert("has_input", &ctx.input_deserializer.is_some());
+        match ctx.input_deserializer {
+            None => self.tera_context.insert("input_deserializer", "Unit"),
+            Some(ref input) => self.tera_context.insert("input_deserializer", input),
+        }
+
+        // eprintln!(
+        //     "😁 {:?} / {:?}",
+        //     &ctx.input_deserializer, &ctx.output_deserializer
+        // );
+
+        let has_output = ctx.output_deserializer.is_some();
+        self.tera_context.insert("has_output", &has_output);
+
+        match ctx.output_deserializer {
+            None => self.tera_context.insert("output_deserializer", "Unit"),
+            Some(ref output) => self.tera_context.insert("output_deserializer", output),
+        }
+
+        self.tera_context.insert("error_deserializer", &ctx.error_deserializer);
+
+        let tera = get_tera("dart_event");
+        match tera.render("event_template.tera", &self.tera_context) {
+            Ok(r) => Some(r),
+            Err(e) => {
+                log::error!("{:?}", e);
+                None
+            }
+        }
+    }
+}

+ 45 - 0
shared-lib/lib-infra/src/code_gen/dart_event/event_template.tera

@@ -0,0 +1,45 @@
+class {{ event_class }} {
+{%- if has_input  %}
+     {{ input_deserializer }} request;
+     {{ event_class }}(this.request);
+{%- else %}
+    {{ event_class }}();
+{%- endif %}
+
+    Future<Either<{{ output_deserializer }}, {{ error_deserializer }}>> send() {
+
+{%- if has_input  %}
+    final request = FFIRequest.create()
+          ..event = {{ event }}.toString()
+          ..payload = requestToBytes(this.request);
+
+    return Dispatch.asyncRequest(request)
+        .then((bytesResult) => bytesResult.fold(
+
+        {%- if has_output  %}
+           (okBytes) => left({{ output_deserializer }}.fromBuffer(okBytes)),
+        {%- else %}
+           (bytes) => left(unit),
+        {%- endif %}
+           (errBytes) => right({{ error_deserializer }}.fromBuffer(errBytes)),
+        ));
+
+{%- else %}
+     final request = FFIRequest.create()
+        ..event = {{ event }}.toString();
+        {%- if has_input  %}
+        ..payload = bytes;
+        {%- endif %}
+
+     return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
+     {%- if has_output  %}
+        (okBytes) => left({{ output_deserializer }}.fromBuffer(okBytes)),
+     {%- else %}
+        (bytes) => left(unit),
+     {%- endif %}
+        (errBytes) => right({{ error_deserializer }}.fromBuffer(errBytes)),
+      ));
+{%- endif %}
+    }
+}
+

+ 5 - 0
shared-lib/lib-infra/src/code_gen/dart_event/mod.rs

@@ -0,0 +1,5 @@
+#![allow(clippy::module_inception)]
+mod dart_event;
+mod event_template;
+
+pub use dart_event::*;

+ 3 - 3
shared-lib/lib-infra/src/proto_gen/flowy_toml.rs → shared-lib/lib-infra/src/code_gen/flowy_toml.rs

@@ -15,9 +15,9 @@ impl FlowyConfig {
 }
 
 pub struct CrateConfig {
-    pub(crate) crate_path: String,
-    pub(crate) folder_name: String,
-    pub(crate) flowy_config: FlowyConfig,
+    pub crate_path: String,
+    pub folder_name: String,
+    pub flowy_config: FlowyConfig,
 }
 
 impl CrateConfig {

+ 17 - 0
shared-lib/lib-infra/src/code_gen/mod.rs

@@ -0,0 +1,17 @@
+#[cfg(feature = "pb_gen")]
+pub mod protobuf_file;
+
+#[cfg(feature = "dart_event")]
+pub mod dart_event;
+
+#[cfg(any(feature = "pb_gen", feature = "dart_event"))]
+mod flowy_toml;
+
+#[cfg(any(feature = "pb_gen", feature = "dart_event"))]
+pub mod util;
+
+#[derive(serde::Serialize, serde::Deserialize)]
+pub struct ProtoCache {
+    pub structs: Vec<String>,
+    pub enums: Vec<String>,
+}

+ 5 - 5
shared-lib/lib-infra/src/proto_gen/ast.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/ast.rs

@@ -2,9 +2,9 @@
 #![allow(dead_code)]
 #![allow(unused_imports)]
 #![allow(unused_results)]
-use crate::proto_gen::template::{EnumTemplate, StructTemplate};
-use crate::proto_gen::util::*;
-use crate::proto_gen::{parse_crate_info_from_path, ProtoFile, ProtobufCrateContext};
+use crate::code_gen::protobuf_file::template::{EnumTemplate, StructTemplate};
+use crate::code_gen::protobuf_file::{parse_crate_info_from_path, ProtoFile, ProtobufCrateContext};
+use crate::code_gen::util::*;
 use fancy_regex::Regex;
 use flowy_ast::*;
 use lazy_static::lazy_static;
@@ -12,8 +12,8 @@ use std::{fs::File, io::Read, path::Path};
 use syn::Item;
 use walkdir::WalkDir;
 
-pub fn parse_crate_protobuf(roots: Vec<String>) -> Vec<ProtobufCrateContext> {
-    let crate_infos = parse_crate_info_from_path(roots);
+pub fn parse_crate_protobuf(crate_paths: Vec<String>) -> Vec<ProtobufCrateContext> {
+    let crate_infos = parse_crate_info_from_path(crate_paths);
     crate_infos
         .into_iter()
         .map(|crate_info| {

+ 26 - 16
shared-lib/lib-infra/src/pb.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/mod.rs

@@ -1,9 +1,15 @@
 #![allow(unused_imports)]
 #![allow(unused_attributes)]
 #![allow(dead_code)]
+mod ast;
+mod proto_gen;
+mod proto_info;
+mod template;
+
+pub use proto_gen::*;
+pub use proto_info::*;
 
 #[cfg(feature = "proto_gen")]
-use crate::proto_gen::*;
 use log::info;
 use std::fs::File;
 use std::io::Write;
@@ -11,12 +17,12 @@ use std::path::PathBuf;
 use std::process::Command;
 use walkdir::WalkDir;
 
-pub fn gen_files(crate_name: &str, proto_file_dir: &str) {
+pub fn gen(crate_name: &str, proto_file_dir: &str) {
     // 1. generate the proto files to proto_file_dir
     #[cfg(feature = "proto_gen")]
     let _ = gen_protos(crate_name);
 
-    let mut paths = vec![];
+    let mut proto_file_paths = vec![];
     let mut file_names = vec![];
 
     for (path, file_name) in WalkDir::new(proto_file_dir)
@@ -31,26 +37,31 @@ pub fn gen_files(crate_name: &str, proto_file_dir: &str) {
         if path.ends_with(".proto") {
             // https://stackoverflow.com/questions/49077147/how-can-i-force-build-rs-to-run-again-without-cleaning-my-whole-project
             println!("cargo:rerun-if-changed={}", path);
-            paths.push(path);
+            proto_file_paths.push(path);
             file_names.push(file_name);
         }
     }
-    println!("cargo:rerun-if-changed=build.rs");
     let protoc_bin_path = protoc_bin_vendored::protoc_bin_path().unwrap();
 
     // 2. generate the protobuf files(Dart)
     #[cfg(feature = "dart")]
-    generate_dart_protobuf_files(crate_name, proto_file_dir, &paths, &file_names, &protoc_bin_path);
+    generate_dart_protobuf_files(
+        crate_name,
+        proto_file_dir,
+        &proto_file_paths,
+        &file_names,
+        &protoc_bin_path,
+    );
 
     // 3. generate the protobuf files(Rust)
-    generate_rust_protobuf_files(&protoc_bin_path, &paths, proto_file_dir);
+    generate_rust_protobuf_files(&protoc_bin_path, &proto_file_paths, proto_file_dir);
 }
 
-fn generate_rust_protobuf_files(protoc_bin_path: &PathBuf, input_paths: &Vec<String>, proto_file_dir: &str) {
+fn generate_rust_protobuf_files(protoc_bin_path: &PathBuf, proto_file_paths: &Vec<String>, proto_file_dir: &str) {
     protoc_rust::Codegen::new()
         .out_dir("./src/protobuf/model")
         .protoc_path(protoc_bin_path)
-        .inputs(input_paths)
+        .inputs(proto_file_paths)
         .include(proto_file_dir)
         .run()
         .expect("Running protoc failed.");
@@ -62,7 +73,7 @@ fn generate_dart_protobuf_files(
     root: &str,
     paths: &Vec<String>,
     file_names: &Vec<String>,
-    proto_path: &PathBuf,
+    protoc_bin_path: &PathBuf,
 ) {
     if std::env::var("CARGO_MAKE_WORKING_DIRECTORY").is_err() {
         log::warn!("CARGO_MAKE_WORKING_DIRECTORY was not set, skip generate dart pb");
@@ -76,15 +87,15 @@ fn generate_dart_protobuf_files(
 
     let workspace_dir = std::env::var("CARGO_MAKE_WORKING_DIRECTORY").unwrap();
     let flutter_sdk_path = std::env::var("FLUTTER_FLOWY_SDK_PATH").unwrap();
-    let output = format!("{}/{}/{}", workspace_dir, flutter_sdk_path, name);
+    let output = format!("{}/{}/lib/protobuf/{}", workspace_dir, flutter_sdk_path, name);
     if !std::path::Path::new(&output).exists() {
         std::fs::create_dir_all(&output).unwrap();
     }
     check_pb_dart_plugin();
-    let proto_path = proto_path.to_str().unwrap().to_owned();
+    let protoc_bin_path = protoc_bin_path.to_str().unwrap().to_owned();
     paths.iter().for_each(|path| {
         if cmd_lib::run_cmd! {
-            ${proto_path} --dart_out=${output} --proto_path=${root} ${path}
+            ${protoc_bin_path} --dart_out=${output} --proto_path=${root} ${path}
         }
         .is_err()
         {
@@ -147,9 +158,8 @@ fn run_command(cmd: &str) -> bool {
 
 #[cfg(feature = "proto_gen")]
 fn gen_protos(crate_name: &str) -> Vec<ProtobufCrate> {
-    let cache_path = env!("CARGO_MANIFEST_DIR");
-    let root = std::fs::canonicalize(".").unwrap().as_path().display().to_string();
-    let crate_context = ProtoGenerator::gen(crate_name, &root, cache_path);
+    let crate_path = std::fs::canonicalize(".").unwrap().as_path().display().to_string();
+    let crate_context = ProtoGenerator::gen(crate_name, &crate_path);
     let proto_crates = crate_context
         .iter()
         .map(|info| info.protobuf_crate.clone())

+ 8 - 13
shared-lib/lib-infra/src/proto_gen/proto_gen.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/proto_gen.rs

@@ -2,17 +2,18 @@
 #![allow(dead_code)]
 #![allow(unused_imports)]
 #![allow(unused_results)]
-use crate::proto_gen::ast::parse_crate_protobuf;
-use crate::proto_gen::proto_info::ProtobufCrateContext;
-use crate::proto_gen::util::*;
-use crate::proto_gen::ProtoFile;
+use crate::code_gen::protobuf_file::ast::parse_crate_protobuf;
+use crate::code_gen::protobuf_file::proto_info::ProtobufCrateContext;
+use crate::code_gen::protobuf_file::ProtoFile;
+use crate::code_gen::util::*;
+use crate::code_gen::ProtoCache;
 use std::fs::File;
 use std::path::Path;
 use std::{fs::OpenOptions, io::Write};
 
-pub(crate) struct ProtoGenerator();
+pub struct ProtoGenerator();
 impl ProtoGenerator {
-    pub(crate) fn gen(crate_name: &str, crate_path: &str, cache_path: &str) -> Vec<ProtobufCrateContext> {
+    pub fn gen(crate_name: &str, crate_path: &str) -> Vec<ProtobufCrateContext> {
         let crate_contexts = parse_crate_protobuf(vec![crate_path.to_owned()]);
         write_proto_files(&crate_contexts);
         write_rust_crate_mod_file(&crate_contexts);
@@ -24,7 +25,7 @@ impl ProtoGenerator {
 
         let cache = ProtoCache::from_crate_contexts(&crate_contexts);
         let cache_str = serde_json::to_string(&cache).unwrap();
-        let cache_dir = format!("{}/.cache/{}", cache_path, crate_name);
+        let cache_dir = format!("{}/{}", cache_dir(), crate_name);
         if !Path::new(&cache_dir).exists() {
             std::fs::create_dir_all(&cache_dir).unwrap();
         }
@@ -92,12 +93,6 @@ fn write_rust_crate_mod_file(crate_contexts: &[ProtobufCrateContext]) {
     }
 }
 
-#[derive(serde::Serialize, serde::Deserialize)]
-pub struct ProtoCache {
-    pub structs: Vec<String>,
-    pub enums: Vec<String>,
-}
-
 impl ProtoCache {
     fn from_crate_contexts(crate_contexts: &[ProtobufCrateContext]) -> Self {
         let proto_files = crate_contexts

+ 2 - 2
shared-lib/lib-infra/src/proto_gen/proto_info.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/proto_info.rs

@@ -1,6 +1,6 @@
 #![allow(dead_code)]
-use crate::proto_gen::flowy_toml::{parse_crate_config_from, CrateConfig};
-use crate::proto_gen::util::*;
+use crate::code_gen::flowy_toml::{parse_crate_config_from, CrateConfig};
+use crate::code_gen::util::*;
 use std::fs::OpenOptions;
 use std::io::Write;
 use walkdir::WalkDir;

+ 2 - 2
shared-lib/lib-infra/src/proto_gen/template/derive_meta/derive_meta.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/template/derive_meta/derive_meta.rs

@@ -1,4 +1,4 @@
-use crate::proto_gen::template::get_tera;
+use crate::code_gen::util::get_tera;
 use itertools::Itertools;
 use tera::Context;
 
@@ -23,7 +23,7 @@ impl ProtobufDeriveMeta {
         self.context.insert("names", &self.structs);
         self.context.insert("enums", &self.enums);
 
-        let tera = get_tera("derive_meta");
+        let tera = get_tera("protobuf_file/template/derive_meta");
         match tera.render("derive_meta.tera", &self.context) {
             Ok(r) => Some(r),
             Err(e) => {

+ 0 - 0
shared-lib/lib-infra/src/proto_gen/template/derive_meta/derive_meta.tera → shared-lib/lib-infra/src/code_gen/protobuf_file/template/derive_meta/derive_meta.tera


+ 0 - 0
shared-lib/lib-infra/src/proto_gen/template/derive_meta/mod.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/template/derive_meta/mod.rs


+ 5 - 0
shared-lib/lib-infra/src/code_gen/protobuf_file/template/mod.rs

@@ -0,0 +1,5 @@
+mod derive_meta;
+mod proto_file;
+
+pub use derive_meta::*;
+pub use proto_file::*;

+ 0 - 0
shared-lib/lib-infra/src/proto_gen/template/proto_file/enum.tera → shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/enum.tera


+ 3 - 3
shared-lib/lib-infra/src/proto_gen/template/proto_file/enum_template.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/enum_template.rs

@@ -1,5 +1,5 @@
-use crate::proto_gen::ast::FlowyEnum;
-use crate::proto_gen::template::get_tera;
+use crate::code_gen::protobuf_file::ast::FlowyEnum;
+use crate::code_gen::util::get_tera;
 use tera::Context;
 
 pub struct EnumTemplate {
@@ -26,7 +26,7 @@ impl EnumTemplate {
 
     pub fn render(&mut self) -> Option<String> {
         self.context.insert("items", &self.items);
-        let tera = get_tera("proto_file");
+        let tera = get_tera("protobuf_file/template/proto_file");
         match tera.render("enum.tera", &self.context) {
             Ok(r) => Some(r),
             Err(e) => {

+ 0 - 0
shared-lib/lib-infra/src/proto_gen/template/proto_file/mod.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/mod.rs


+ 0 - 0
shared-lib/lib-infra/src/proto_gen/template/proto_file/struct.tera → shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/struct.tera


+ 2 - 3
shared-lib/lib-infra/src/proto_gen/template/proto_file/struct_template.rs → shared-lib/lib-infra/src/code_gen/protobuf_file/template/proto_file/struct_template.rs

@@ -1,7 +1,6 @@
+use crate::code_gen::util::get_tera;
 use flowy_ast::*;
 use phf::phf_map;
-
-use crate::proto_gen::template::get_tera;
 use tera::Context;
 
 // Protobuf data type : https://developers.google.com/protocol-buffers/docs/proto3
@@ -95,7 +94,7 @@ impl StructTemplate {
 
     pub fn render(&mut self) -> Option<String> {
         self.context.insert("fields", &self.fields);
-        let tera = get_tera("proto_file");
+        let tera = get_tera("protobuf_file/template/proto_file");
         match tera.render("struct.tera", &self.context) {
             Ok(r) => Some(r),
             Err(e) => {

+ 32 - 2
shared-lib/lib-infra/src/proto_gen/util.rs → shared-lib/lib-infra/src/code_gen/util.rs

@@ -1,11 +1,11 @@
 use console::Style;
-
 use similar::{ChangeTag, TextDiff};
 use std::{
     fs::{File, OpenOptions},
     io::{Read, Write},
     path::Path,
 };
+use tera::Tera;
 use walkdir::WalkDir;
 
 pub fn read_file(path: &str) -> Option<String> {
@@ -100,7 +100,7 @@ pub fn create_dir_if_not_exist(dir: &str) {
 }
 
 #[allow(dead_code)]
-pub(crate) fn walk_dir<F1, F2>(dir: &str, filter: F2, mut path_and_name: F1)
+pub fn walk_dir<F1, F2>(dir: &str, filter: F2, mut path_and_name: F1)
 where
     F1: FnMut(String, String),
     F2: Fn(&walkdir::DirEntry) -> bool,
@@ -126,3 +126,33 @@ pub fn suffix_relative_to_path(path: &str, base: &str) -> String {
     let path = Path::new(path);
     path.strip_prefix(base).unwrap().to_str().unwrap().to_owned()
 }
+
+pub fn get_tera(directory: &str) -> Tera {
+    let mut root = format!("{}/src/code_gen/", env!("CARGO_MANIFEST_DIR"));
+    root.push_str(directory);
+
+    let root_absolute_path = match std::fs::canonicalize(&root) {
+        Ok(p) => p.as_path().display().to_string(),
+        Err(e) => {
+            panic!("❌ Canonicalize file path {} failed {:?}", root, e);
+        }
+    };
+
+    let mut template_path = format!("{}/**/*.tera", root_absolute_path);
+    if cfg!(windows) {
+        // remove "\\?\" prefix on windows
+        template_path = format!("{}/**/*.tera", &root_absolute_path[4..]);
+    }
+
+    match Tera::new(template_path.as_ref()) {
+        Ok(t) => t,
+        Err(e) => {
+            log::error!("Parsing error(s): {}", e);
+            ::std::process::exit(1);
+        }
+    }
+}
+
+pub fn cache_dir() -> String {
+    format!("{}/.cache", env!("CARGO_MANIFEST_DIR"))
+}

+ 1 - 6
shared-lib/lib-infra/src/lib.rs

@@ -1,12 +1,7 @@
+pub mod code_gen;
 pub mod future;
 pub mod retry;
 
-#[cfg(feature = "pb_gen")]
-pub mod pb;
-
-#[cfg(feature = "proto_gen")]
-pub mod proto_gen;
-
 #[allow(dead_code)]
 pub fn uuid_string() -> String {
     uuid::Uuid::new_v4().to_string()

+ 0 - 10
shared-lib/lib-infra/src/proto_gen/mod.rs

@@ -1,10 +0,0 @@
-#![allow(clippy::module_inception)]
-mod ast;
-mod flowy_toml;
-mod proto_gen;
-mod proto_info;
-mod template;
-pub mod util;
-
-pub use proto_gen::*;
-pub use proto_info::*;

+ 0 - 47
shared-lib/lib-infra/src/proto_gen/template/mod.rs

@@ -1,47 +0,0 @@
-mod derive_meta;
-mod proto_file;
-
-pub use derive_meta::*;
-pub use proto_file::*;
-use std::fs::File;
-use std::io::Read;
-use tera::Tera;
-
-pub fn get_tera(directory: &str) -> Tera {
-    let mut root = format!("{}/src/proto_gen/template/", env!("CARGO_MANIFEST_DIR"));
-    root.push_str(directory);
-
-    let root_absolute_path = match std::fs::canonicalize(&root) {
-        Ok(p) => p.as_path().display().to_string(),
-        Err(e) => {
-            panic!("❌ Canonicalize file path {} failed {:?}", root, e);
-        }
-    };
-
-    let mut template_path = format!("{}/**/*.tera", root_absolute_path);
-    if cfg!(windows) {
-        // remove "\\?\" prefix on windows
-        template_path = format!("{}/**/*.tera", &root_absolute_path[4..]);
-    }
-
-    match Tera::new(template_path.as_ref()) {
-        Ok(t) => t,
-        Err(e) => {
-            log::error!("Parsing error(s): {}", e);
-            ::std::process::exit(1);
-        }
-    }
-}
-
-#[allow(dead_code)]
-pub fn read_file(path: &str) -> Option<String> {
-    let mut file = File::open(path).unwrap_or_else(|_| panic!("Unable to open file at {}", path));
-    let mut content = String::new();
-    match file.read_to_string(&mut content) {
-        Ok(_) => Some(content),
-        Err(e) => {
-            log::error!("{}, with error: {:?}", path, e);
-            Some("".to_string())
-        }
-    }
-}

+ 2 - 2
shared-lib/lib-ws/build.rs

@@ -1,5 +1,5 @@
-use lib_infra::pb;
+use lib_infra::code_gen;
 
 fn main() {
-    pb::gen_files(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
+    code_gen::protobuf_file::gen(env!("CARGO_PKG_NAME"), "./src/protobuf/proto");
 }