Forráskód Böngészése

add strum crate for event stringtify

appflowy 3 éve
szülő
commit
18d13a3cb2
58 módosított fájl, 470 hozzáadás és 450 törlés
  1. 1 5
      app_flowy/lib/welcome/infrastructure/i_welcome_impl.dart
  2. 1 1
      app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart
  3. 4 4
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pb.dart
  4. 30 30
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbenum.dart
  5. 7 7
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbjson.dart
  6. 4 4
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pb.dart
  7. 24 24
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbenum.dart
  8. 7 7
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbjson.dart
  9. 35 0
      rust-lib/flowy-derive/src/dart_event/mod.rs
  10. 2 2
      rust-lib/flowy-derive/src/derive_cache/derive_cache.rs
  11. 3 0
      rust-lib/flowy-document/Cargo.toml
  12. 1 5
      rust-lib/flowy-document/src/event.rs
  13. 5 5
      rust-lib/flowy-document/tests/editor/helper.rs
  14. 3 3
      rust-lib/flowy-sdk/src/deps_resolve/workspace_deps_impl.rs
  15. 7 11
      rust-lib/flowy-test/src/builder.rs
  16. 4 4
      rust-lib/flowy-test/src/helper.rs
  17. 4 1
      rust-lib/flowy-test/src/tester.rs
  18. 2 1
      rust-lib/flowy-user/Cargo.toml
  19. 4 4
      rust-lib/flowy-user/src/entities/parser/user_email.rs
  20. 5 5
      rust-lib/flowy-user/src/entities/parser/user_name.rs
  21. 6 6
      rust-lib/flowy-user/src/entities/parser/user_password.rs
  22. 2 2
      rust-lib/flowy-user/src/entities/user_update.rs
  23. 13 13
      rust-lib/flowy-user/src/errors.rs
  24. 5 6
      rust-lib/flowy-user/src/event.rs
  25. 85 85
      rust-lib/flowy-user/src/protobuf/model/errors.rs
  26. 2 2
      rust-lib/flowy-user/src/protobuf/proto/errors.proto
  27. 7 7
      rust-lib/flowy-user/src/services/user/database.rs
  28. 3 3
      rust-lib/flowy-user/src/services/user/user_server/server_api.rs
  29. 2 2
      rust-lib/flowy-user/src/services/user/user_server/server_api_mock.rs
  30. 5 5
      rust-lib/flowy-user/src/services/user/user_session.rs
  31. 1 1
      rust-lib/flowy-user/tests/event/helper.rs
  32. 5 5
      rust-lib/flowy-user/tests/event/sign_in_test.rs
  33. 4 4
      rust-lib/flowy-user/tests/event/sign_up_test.rs
  34. 3 3
      rust-lib/flowy-user/tests/event/user_status_test.rs
  35. 14 14
      rust-lib/flowy-user/tests/event/user_update_test.rs
  36. 2 0
      rust-lib/flowy-workspace/Cargo.toml
  37. 3 3
      rust-lib/flowy-workspace/src/entities/app/app_create.rs
  38. 2 2
      rust-lib/flowy-workspace/src/entities/app/app_delete.rs
  39. 1 1
      rust-lib/flowy-workspace/src/entities/app/app_query.rs
  40. 4 4
      rust-lib/flowy-workspace/src/entities/app/app_update.rs
  41. 4 4
      rust-lib/flowy-workspace/src/entities/view/view_create.rs
  42. 2 2
      rust-lib/flowy-workspace/src/entities/view/view_delete.rs
  43. 2 2
      rust-lib/flowy-workspace/src/entities/view/view_query.rs
  44. 5 5
      rust-lib/flowy-workspace/src/entities/view/view_update.rs
  45. 3 3
      rust-lib/flowy-workspace/src/entities/workspace/workspace_create.rs
  46. 2 2
      rust-lib/flowy-workspace/src/entities/workspace/workspace_delete.rs
  47. 15 1
      rust-lib/flowy-workspace/src/entities/workspace/workspace_query.rs
  48. 2 2
      rust-lib/flowy-workspace/src/entities/workspace/workspace_update.rs
  49. 12 12
      rust-lib/flowy-workspace/src/errors.rs
  50. 1 14
      rust-lib/flowy-workspace/src/event.rs
  51. 2 2
      rust-lib/flowy-workspace/src/handlers/workspace_handler.rs
  52. 58 58
      rust-lib/flowy-workspace/src/protobuf/model/errors.rs
  53. 2 2
      rust-lib/flowy-workspace/src/protobuf/proto/errors.proto
  54. 3 3
      rust-lib/flowy-workspace/src/services/workspace_controller.rs
  55. 7 7
      rust-lib/flowy-workspace/tests/event/app_test.rs
  56. 10 10
      rust-lib/flowy-workspace/tests/event/helper.rs
  57. 4 4
      rust-lib/flowy-workspace/tests/event/view_test.rs
  58. 14 26
      rust-lib/flowy-workspace/tests/event/workspace_test.rs

+ 1 - 5
app_flowy/lib/welcome/infrastructure/i_welcome_impl.dart

@@ -6,7 +6,6 @@ import 'package:app_flowy/welcome/domain/i_welcome.dart';
 import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
 import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
 import 'package:app_flowy/workspace/presentation/workspace/workspace_select_screen.dart';
-import 'package:flowy_infra/flowy_logger.dart';
 import 'package:flowy_infra/time/duration.dart';
 import 'package:flowy_infra_ui/widget/route/animation.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
@@ -44,11 +43,8 @@ class WelcomeRoute implements IWelcomeRoute {
           (workspace) =>
               _pushToScreen(context, HomeScreen(repo.user, workspace.id)),
           (error) async {
-            // assert(error.code == WsErrCode.RecordNotFound);
-            // error shoule be RecordNotFound
-            Log.error(error);
+            assert(error.code == WsErrCode.CurrentWorkspaceNotFound);
             final screen = WorkspaceSelectScreen(repo: repo);
-
             final workspaceId = await Navigator.of(context).push(
               PageRoutes.fade(
                 () => screen,

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

@@ -17,7 +17,7 @@ import 'package:flowy_sdk/protobuf/flowy-document/protobuf.dart';
 // ignore: unused_import
 import 'package:flowy_sdk/protobuf/flowy-infra/protobuf.dart';
 import 'package:protobuf/protobuf.dart';
-import 'dart:convert' show utf8;
+// import 'dart:convert' show utf8;
 import 'error.dart';
 
 part 'code_gen.dart';

+ 4 - 4
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pb.dart

@@ -15,14 +15,14 @@ export 'errors.pbenum.dart';
 
 class UserError extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserError', createEmptyInstance: create)
-    ..e<UserErrCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: UserErrCode.Unknown, valueOf: UserErrCode.valueOf, enumValues: UserErrCode.values)
+    ..e<ErrorCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: ErrorCode.Unknown, valueOf: ErrorCode.valueOf, enumValues: ErrorCode.values)
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg')
     ..hasRequiredFields = false
   ;
 
   UserError._() : super();
   factory UserError({
-    UserErrCode? code,
+    ErrorCode? code,
     $core.String? msg,
   }) {
     final _result = create();
@@ -56,9 +56,9 @@ class UserError extends $pb.GeneratedMessage {
   static UserError? _defaultInstance;
 
   @$pb.TagNumber(1)
-  UserErrCode get code => $_getN(0);
+  ErrorCode get code => $_getN(0);
   @$pb.TagNumber(1)
-  set code(UserErrCode v) { setField(1, v); }
+  set code(ErrorCode v) { setField(1, v); }
   @$pb.TagNumber(1)
   $core.bool hasCode() => $_has(0);
   @$pb.TagNumber(1)

+ 30 - 30
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbenum.dart

@@ -9,34 +9,34 @@
 import 'dart:core' as $core;
 import 'package:protobuf/protobuf.dart' as $pb;
 
-class UserErrCode extends $pb.ProtobufEnum {
-  static const UserErrCode Unknown = UserErrCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
-  static const UserErrCode UserDatabaseInitFailed = UserErrCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInitFailed');
-  static const UserErrCode UserDatabaseWriteLocked = UserErrCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseWriteLocked');
-  static const UserErrCode UserDatabaseReadLocked = UserErrCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseReadLocked');
-  static const UserErrCode UserDatabaseDidNotMatch = UserErrCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseDidNotMatch');
-  static const UserErrCode UserDatabaseInternalError = UserErrCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInternalError');
-  static const UserErrCode SqlInternalError = UserErrCode._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SqlInternalError');
-  static const UserErrCode UserNotLoginYet = UserErrCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
-  static const UserErrCode ReadCurrentIdFailed = UserErrCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadCurrentIdFailed');
-  static const UserErrCode WriteCurrentIdFailed = UserErrCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WriteCurrentIdFailed');
-  static const UserErrCode EmailIsEmpty = UserErrCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailIsEmpty');
-  static const UserErrCode EmailFormatInvalid = UserErrCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailFormatInvalid');
-  static const UserErrCode EmailAlreadyExists = UserErrCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailAlreadyExists');
-  static const UserErrCode PasswordIsEmpty = UserErrCode._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordIsEmpty');
-  static const UserErrCode PasswordTooLong = UserErrCode._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordTooLong');
-  static const UserErrCode PasswordContainsForbidCharacters = UserErrCode._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordContainsForbidCharacters');
-  static const UserErrCode PasswordFormatInvalid = UserErrCode._(33, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordFormatInvalid');
-  static const UserErrCode UserNameTooLong = UserErrCode._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameTooLong');
-  static const UserErrCode UserNameContainsForbiddenCharacters = UserErrCode._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameContainsForbiddenCharacters');
-  static const UserErrCode UserNameIsEmpty = UserErrCode._(42, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameIsEmpty');
-  static const UserErrCode UserWorkspaceInvalid = UserErrCode._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserWorkspaceInvalid');
-  static const UserErrCode UserIdInvalid = UserErrCode._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid');
-  static const UserErrCode CreateDefaultWorkspaceFailed = UserErrCode._(52, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateDefaultWorkspaceFailed');
-  static const UserErrCode DefaultWorkspaceAlreadyExist = UserErrCode._(53, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DefaultWorkspaceAlreadyExist');
-  static const UserErrCode ServerError = UserErrCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ServerError');
+class ErrorCode extends $pb.ProtobufEnum {
+  static const ErrorCode Unknown = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
+  static const ErrorCode UserDatabaseInitFailed = ErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInitFailed');
+  static const ErrorCode UserDatabaseWriteLocked = ErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseWriteLocked');
+  static const ErrorCode UserDatabaseReadLocked = ErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseReadLocked');
+  static const ErrorCode UserDatabaseDidNotMatch = ErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseDidNotMatch');
+  static const ErrorCode UserDatabaseInternalError = ErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInternalError');
+  static const ErrorCode SqlInternalError = ErrorCode._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SqlInternalError');
+  static const ErrorCode UserNotLoginYet = ErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
+  static const ErrorCode ReadCurrentIdFailed = ErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadCurrentIdFailed');
+  static const ErrorCode WriteCurrentIdFailed = ErrorCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WriteCurrentIdFailed');
+  static const ErrorCode EmailIsEmpty = ErrorCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailIsEmpty');
+  static const ErrorCode EmailFormatInvalid = ErrorCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailFormatInvalid');
+  static const ErrorCode EmailAlreadyExists = ErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailAlreadyExists');
+  static const ErrorCode PasswordIsEmpty = ErrorCode._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordIsEmpty');
+  static const ErrorCode PasswordTooLong = ErrorCode._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordTooLong');
+  static const ErrorCode PasswordContainsForbidCharacters = ErrorCode._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordContainsForbidCharacters');
+  static const ErrorCode PasswordFormatInvalid = ErrorCode._(33, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordFormatInvalid');
+  static const ErrorCode UserNameTooLong = ErrorCode._(40, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameTooLong');
+  static const ErrorCode UserNameContainsForbiddenCharacters = ErrorCode._(41, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameContainsForbiddenCharacters');
+  static const ErrorCode UserNameIsEmpty = ErrorCode._(42, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameIsEmpty');
+  static const ErrorCode UserWorkspaceInvalid = ErrorCode._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserWorkspaceInvalid');
+  static const ErrorCode UserIdInvalid = ErrorCode._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid');
+  static const ErrorCode CreateDefaultWorkspaceFailed = ErrorCode._(52, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateDefaultWorkspaceFailed');
+  static const ErrorCode DefaultWorkspaceAlreadyExist = ErrorCode._(53, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DefaultWorkspaceAlreadyExist');
+  static const ErrorCode ServerError = ErrorCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ServerError');
 
-  static const $core.List<UserErrCode> values = <UserErrCode> [
+  static const $core.List<ErrorCode> values = <ErrorCode> [
     Unknown,
     UserDatabaseInitFailed,
     UserDatabaseWriteLocked,
@@ -64,9 +64,9 @@ class UserErrCode extends $pb.ProtobufEnum {
     ServerError,
   ];
 
-  static final $core.Map<$core.int, UserErrCode> _byValue = $pb.ProtobufEnum.initByValue(values);
-  static UserErrCode? valueOf($core.int value) => _byValue[value];
+  static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static ErrorCode? valueOf($core.int value) => _byValue[value];
 
-  const UserErrCode._($core.int v, $core.String n) : super(v, n);
+  const ErrorCode._($core.int v, $core.String n) : super(v, n);
 }
 

+ 7 - 7
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-user/errors.pbjson.dart

@@ -8,9 +8,9 @@
 import 'dart:core' as $core;
 import 'dart:convert' as $convert;
 import 'dart:typed_data' as $typed_data;
-@$core.Deprecated('Use userErrCodeDescriptor instead')
-const UserErrCode$json = const {
-  '1': 'UserErrCode',
+@$core.Deprecated('Use errorCodeDescriptor instead')
+const ErrorCode$json = const {
+  '1': 'ErrorCode',
   '2': const [
     const {'1': 'Unknown', '2': 0},
     const {'1': 'UserDatabaseInitFailed', '2': 1},
@@ -40,16 +40,16 @@ const UserErrCode$json = const {
   ],
 };
 
-/// Descriptor for `UserErrCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List userErrCodeDescriptor = $convert.base64Decode('CgtVc2VyRXJyQ29kZRILCgdVbmtub3duEAASGgoWVXNlckRhdGFiYXNlSW5pdEZhaWxlZBABEhsKF1VzZXJEYXRhYmFzZVdyaXRlTG9ja2VkEAISGgoWVXNlckRhdGFiYXNlUmVhZExvY2tlZBADEhsKF1VzZXJEYXRhYmFzZURpZE5vdE1hdGNoEAQSHQoZVXNlckRhdGFiYXNlSW50ZXJuYWxFcnJvchAFEhQKEFNxbEludGVybmFsRXJyb3IQBhITCg9Vc2VyTm90TG9naW5ZZXQQChIXChNSZWFkQ3VycmVudElkRmFpbGVkEAsSGAoUV3JpdGVDdXJyZW50SWRGYWlsZWQQDBIQCgxFbWFpbElzRW1wdHkQFBIWChJFbWFpbEZvcm1hdEludmFsaWQQFRIWChJFbWFpbEFscmVhZHlFeGlzdHMQFhITCg9QYXNzd29yZElzRW1wdHkQHhITCg9QYXNzd29yZFRvb0xvbmcQHxIkCiBQYXNzd29yZENvbnRhaW5zRm9yYmlkQ2hhcmFjdGVycxAgEhkKFVBhc3N3b3JkRm9ybWF0SW52YWxpZBAhEhMKD1VzZXJOYW1lVG9vTG9uZxAoEicKI1VzZXJOYW1lQ29udGFpbnNGb3JiaWRkZW5DaGFyYWN0ZXJzECkSEwoPVXNlck5hbWVJc0VtcHR5ECoSGAoUVXNlcldvcmtzcGFjZUludmFsaWQQMhIRCg1Vc2VySWRJbnZhbGlkEDMSIAocQ3JlYXRlRGVmYXVsdFdvcmtzcGFjZUZhaWxlZBA0EiAKHERlZmF1bHRXb3Jrc3BhY2VBbHJlYWR5RXhpc3QQNRIPCgtTZXJ2ZXJFcnJvchBk');
+/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSCwoHVW5rbm93bhAAEhoKFlVzZXJEYXRhYmFzZUluaXRGYWlsZWQQARIbChdVc2VyRGF0YWJhc2VXcml0ZUxvY2tlZBACEhoKFlVzZXJEYXRhYmFzZVJlYWRMb2NrZWQQAxIbChdVc2VyRGF0YWJhc2VEaWROb3RNYXRjaBAEEh0KGVVzZXJEYXRhYmFzZUludGVybmFsRXJyb3IQBRIUChBTcWxJbnRlcm5hbEVycm9yEAYSEwoPVXNlck5vdExvZ2luWWV0EAoSFwoTUmVhZEN1cnJlbnRJZEZhaWxlZBALEhgKFFdyaXRlQ3VycmVudElkRmFpbGVkEAwSEAoMRW1haWxJc0VtcHR5EBQSFgoSRW1haWxGb3JtYXRJbnZhbGlkEBUSFgoSRW1haWxBbHJlYWR5RXhpc3RzEBYSEwoPUGFzc3dvcmRJc0VtcHR5EB4SEwoPUGFzc3dvcmRUb29Mb25nEB8SJAogUGFzc3dvcmRDb250YWluc0ZvcmJpZENoYXJhY3RlcnMQIBIZChVQYXNzd29yZEZvcm1hdEludmFsaWQQIRITCg9Vc2VyTmFtZVRvb0xvbmcQKBInCiNVc2VyTmFtZUNvbnRhaW5zRm9yYmlkZGVuQ2hhcmFjdGVycxApEhMKD1VzZXJOYW1lSXNFbXB0eRAqEhgKFFVzZXJXb3Jrc3BhY2VJbnZhbGlkEDISEQoNVXNlcklkSW52YWxpZBAzEiAKHENyZWF0ZURlZmF1bHRXb3Jrc3BhY2VGYWlsZWQQNBIgChxEZWZhdWx0V29ya3NwYWNlQWxyZWFkeUV4aXN0EDUSDwoLU2VydmVyRXJyb3IQZA==');
 @$core.Deprecated('Use userErrorDescriptor instead')
 const UserError$json = const {
   '1': 'UserError',
   '2': const [
-    const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.UserErrCode', '10': 'code'},
+    const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.ErrorCode', '10': 'code'},
     const {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'},
   ],
 };
 
 /// Descriptor for `UserError`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List userErrorDescriptor = $convert.base64Decode('CglVc2VyRXJyb3ISIAoEY29kZRgBIAEoDjIMLlVzZXJFcnJDb2RlUgRjb2RlEhAKA21zZxgCIAEoCVIDbXNn');
+final $typed_data.Uint8List userErrorDescriptor = $convert.base64Decode('CglVc2VyRXJyb3ISHgoEY29kZRgBIAEoDjIKLkVycm9yQ29kZVIEY29kZRIQCgNtc2cYAiABKAlSA21zZw==');

+ 4 - 4
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pb.dart

@@ -15,14 +15,14 @@ export 'errors.pbenum.dart';
 
 class WorkspaceError extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'WorkspaceError', createEmptyInstance: create)
-    ..e<WsErrCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: WsErrCode.Unknown, valueOf: WsErrCode.valueOf, enumValues: WsErrCode.values)
+    ..e<ErrorCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: ErrorCode.Unknown, valueOf: ErrorCode.valueOf, enumValues: ErrorCode.values)
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg')
     ..hasRequiredFields = false
   ;
 
   WorkspaceError._() : super();
   factory WorkspaceError({
-    WsErrCode? code,
+    ErrorCode? code,
     $core.String? msg,
   }) {
     final _result = create();
@@ -56,9 +56,9 @@ class WorkspaceError extends $pb.GeneratedMessage {
   static WorkspaceError? _defaultInstance;
 
   @$pb.TagNumber(1)
-  WsErrCode get code => $_getN(0);
+  ErrorCode get code => $_getN(0);
   @$pb.TagNumber(1)
-  set code(WsErrCode v) { setField(1, v); }
+  set code(ErrorCode v) { setField(1, v); }
   @$pb.TagNumber(1)
   $core.bool hasCode() => $_has(0);
   @$pb.TagNumber(1)

+ 24 - 24
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbenum.dart

@@ -9,28 +9,28 @@
 import 'dart:core' as $core;
 import 'package:protobuf/protobuf.dart' as $pb;
 
-class WsErrCode extends $pb.ProtobufEnum {
-  static const WsErrCode Unknown = WsErrCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
-  static const WsErrCode WorkspaceNameInvalid = WsErrCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceNameInvalid');
-  static const WsErrCode WorkspaceIdInvalid = WsErrCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceIdInvalid');
-  static const WsErrCode AppColorStyleInvalid = WsErrCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppColorStyleInvalid');
-  static const WsErrCode WorkspaceDescInvalid = WsErrCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceDescInvalid');
-  static const WsErrCode CurrentWorkspaceNotFound = WsErrCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CurrentWorkspaceNotFound');
-  static const WsErrCode AppIdInvalid = WsErrCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppIdInvalid');
-  static const WsErrCode AppNameInvalid = WsErrCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppNameInvalid');
-  static const WsErrCode ViewNameInvalid = WsErrCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewNameInvalid');
-  static const WsErrCode ViewThumbnailInvalid = WsErrCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewThumbnailInvalid');
-  static const WsErrCode ViewIdInvalid = WsErrCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewIdInvalid');
-  static const WsErrCode ViewDescInvalid = WsErrCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewDescInvalid');
-  static const WsErrCode DatabaseConnectionFail = WsErrCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseConnectionFail');
-  static const WsErrCode WorkspaceDatabaseError = WsErrCode._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceDatabaseError');
-  static const WsErrCode UserInternalError = WsErrCode._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserInternalError');
-  static const WsErrCode UserNotLoginYet = WsErrCode._(103, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
-  static const WsErrCode UserIdIsEmpty = WsErrCode._(104, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdIsEmpty');
-  static const WsErrCode ServerError = WsErrCode._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ServerError');
-  static const WsErrCode RecordNotFound = WsErrCode._(1001, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RecordNotFound');
+class ErrorCode extends $pb.ProtobufEnum {
+  static const ErrorCode Unknown = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
+  static const ErrorCode WorkspaceNameInvalid = ErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceNameInvalid');
+  static const ErrorCode WorkspaceIdInvalid = ErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceIdInvalid');
+  static const ErrorCode AppColorStyleInvalid = ErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppColorStyleInvalid');
+  static const ErrorCode WorkspaceDescInvalid = ErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceDescInvalid');
+  static const ErrorCode CurrentWorkspaceNotFound = ErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CurrentWorkspaceNotFound');
+  static const ErrorCode AppIdInvalid = ErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppIdInvalid');
+  static const ErrorCode AppNameInvalid = ErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppNameInvalid');
+  static const ErrorCode ViewNameInvalid = ErrorCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewNameInvalid');
+  static const ErrorCode ViewThumbnailInvalid = ErrorCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewThumbnailInvalid');
+  static const ErrorCode ViewIdInvalid = ErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewIdInvalid');
+  static const ErrorCode ViewDescInvalid = ErrorCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewDescInvalid');
+  static const ErrorCode DatabaseConnectionFail = ErrorCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseConnectionFail');
+  static const ErrorCode WorkspaceDatabaseError = ErrorCode._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceDatabaseError');
+  static const ErrorCode UserInternalError = ErrorCode._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserInternalError');
+  static const ErrorCode UserNotLoginYet = ErrorCode._(103, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
+  static const ErrorCode UserIdIsEmpty = ErrorCode._(104, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdIsEmpty');
+  static const ErrorCode ServerError = ErrorCode._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ServerError');
+  static const ErrorCode RecordNotFound = ErrorCode._(1001, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RecordNotFound');
 
-  static const $core.List<WsErrCode> values = <WsErrCode> [
+  static const $core.List<ErrorCode> values = <ErrorCode> [
     Unknown,
     WorkspaceNameInvalid,
     WorkspaceIdInvalid,
@@ -52,9 +52,9 @@ class WsErrCode extends $pb.ProtobufEnum {
     RecordNotFound,
   ];
 
-  static final $core.Map<$core.int, WsErrCode> _byValue = $pb.ProtobufEnum.initByValue(values);
-  static WsErrCode? valueOf($core.int value) => _byValue[value];
+  static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static ErrorCode? valueOf($core.int value) => _byValue[value];
 
-  const WsErrCode._($core.int v, $core.String n) : super(v, n);
+  const ErrorCode._($core.int v, $core.String n) : super(v, n);
 }
 

+ 7 - 7
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-workspace/errors.pbjson.dart

@@ -8,9 +8,9 @@
 import 'dart:core' as $core;
 import 'dart:convert' as $convert;
 import 'dart:typed_data' as $typed_data;
-@$core.Deprecated('Use wsErrCodeDescriptor instead')
-const WsErrCode$json = const {
-  '1': 'WsErrCode',
+@$core.Deprecated('Use errorCodeDescriptor instead')
+const ErrorCode$json = const {
+  '1': 'ErrorCode',
   '2': const [
     const {'1': 'Unknown', '2': 0},
     const {'1': 'WorkspaceNameInvalid', '2': 1},
@@ -34,16 +34,16 @@ const WsErrCode$json = const {
   ],
 };
 
-/// Descriptor for `WsErrCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List wsErrCodeDescriptor = $convert.base64Decode('CglXc0VyckNvZGUSCwoHVW5rbm93bhAAEhgKFFdvcmtzcGFjZU5hbWVJbnZhbGlkEAESFgoSV29ya3NwYWNlSWRJbnZhbGlkEAISGAoUQXBwQ29sb3JTdHlsZUludmFsaWQQAxIYChRXb3Jrc3BhY2VEZXNjSW52YWxpZBAEEhwKGEN1cnJlbnRXb3Jrc3BhY2VOb3RGb3VuZBAFEhAKDEFwcElkSW52YWxpZBAKEhIKDkFwcE5hbWVJbnZhbGlkEAsSEwoPVmlld05hbWVJbnZhbGlkEBQSGAoUVmlld1RodW1ibmFpbEludmFsaWQQFRIRCg1WaWV3SWRJbnZhbGlkEBYSEwoPVmlld0Rlc2NJbnZhbGlkEBcSGgoWRGF0YWJhc2VDb25uZWN0aW9uRmFpbBBkEhoKFldvcmtzcGFjZURhdGFiYXNlRXJyb3IQZRIVChFVc2VySW50ZXJuYWxFcnJvchBmEhMKD1VzZXJOb3RMb2dpbllldBBnEhEKDVVzZXJJZElzRW1wdHkQaBIQCgtTZXJ2ZXJFcnJvchDoBxITCg5SZWNvcmROb3RGb3VuZBDpBw==');
+/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSCwoHVW5rbm93bhAAEhgKFFdvcmtzcGFjZU5hbWVJbnZhbGlkEAESFgoSV29ya3NwYWNlSWRJbnZhbGlkEAISGAoUQXBwQ29sb3JTdHlsZUludmFsaWQQAxIYChRXb3Jrc3BhY2VEZXNjSW52YWxpZBAEEhwKGEN1cnJlbnRXb3Jrc3BhY2VOb3RGb3VuZBAFEhAKDEFwcElkSW52YWxpZBAKEhIKDkFwcE5hbWVJbnZhbGlkEAsSEwoPVmlld05hbWVJbnZhbGlkEBQSGAoUVmlld1RodW1ibmFpbEludmFsaWQQFRIRCg1WaWV3SWRJbnZhbGlkEBYSEwoPVmlld0Rlc2NJbnZhbGlkEBcSGgoWRGF0YWJhc2VDb25uZWN0aW9uRmFpbBBkEhoKFldvcmtzcGFjZURhdGFiYXNlRXJyb3IQZRIVChFVc2VySW50ZXJuYWxFcnJvchBmEhMKD1VzZXJOb3RMb2dpbllldBBnEhEKDVVzZXJJZElzRW1wdHkQaBIQCgtTZXJ2ZXJFcnJvchDoBxITCg5SZWNvcmROb3RGb3VuZBDpBw==');
 @$core.Deprecated('Use workspaceErrorDescriptor instead')
 const WorkspaceError$json = const {
   '1': 'WorkspaceError',
   '2': const [
-    const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.WsErrCode', '10': 'code'},
+    const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.ErrorCode', '10': 'code'},
     const {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'},
   ],
 };
 
 /// Descriptor for `WorkspaceError`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List workspaceErrorDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFcnJvchIeCgRjb2RlGAEgASgOMgouV3NFcnJDb2RlUgRjb2RlEhAKA21zZxgCIAEoCVIDbXNn');
+final $typed_data.Uint8List workspaceErrorDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFcnJvchIeCgRjb2RlGAEgASgOMgouRXJyb3JDb2RlUgRjb2RlEhAKA21zZxgCIAEoCVIDbXNn');

+ 35 - 0
rust-lib/flowy-derive/src/dart_event/mod.rs

@@ -4,3 +4,38 @@ use proc_macro2::TokenStream;
 pub fn expand_enum_derive(_input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
     Ok(TokenStream::default())
 }
+
+// use flowy_ast::{ASTContainer, Ctxt};
+// use proc_macro2::TokenStream;
+//
+// // #[proc_macro_derive(DartEvent, attributes(event_ty))]
+// pub fn expand_enum_derive(input: &syn::DeriveInput) -> Result<TokenStream,
+// Vec<syn::Error>> {     let ctxt = Ctxt::new();
+//     let cont = match ASTContainer::from_ast(&ctxt, input) {
+//         Some(cont) => cont,
+//         None => return Err(ctxt.check().unwrap_err()),
+//     };
+//
+//     let enum_ident = &cont.ident;
+//     let pb_enum = cont.attrs.pb_enum_type().unwrap();
+//
+//     let build_display_pb_enum = cont.data.all_idents().map(|i| {
+//         let a = format_ident!("{}", i.to_string());
+//         let token_stream: TokenStream = quote! {
+//             #enum_ident::#i => f.write_str(&#a)?,
+//         };
+//         token_stream
+//     });
+//
+//     ctxt.check()?;
+//
+//     Ok(quote! {
+//         impl std::fmt::Display for #enum_ident {
+//            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
+// {                 match self {
+//                     #(#build_display_pb_enum)*
+//                 }
+//             }
+//         }
+//     })
+// }

+ 2 - 2
rust-lib/flowy-derive/src/derive_cache/derive_cache.rs

@@ -72,14 +72,14 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         => TypeCategory::Protobuf,
         "ViewType"
         | "WorkspaceEvent"
-        | "WsErrCode"
+        | "ErrorCode"
         | "WorkspaceObservable"
         | "EditorEvent"
         | "DocErrorCode"
         | "FFIStatusCode"
         | "UserStatus"
         | "UserEvent"
-        | "UserErrCode"
+        | "ErrorCode"
         => TypeCategory::Enum,
 
         "Option" => TypeCategory::Opt,

+ 3 - 0
rust-lib/flowy-document/Cargo.toml

@@ -21,5 +21,8 @@ log = "0.4.14"
 tokio = {version = "1.6.0", features = ["sync"]}
 tracing = { version = "0.1", features = ["log"] }
 bytes = { version = "1.0" }
+strum = "0.21"
+strum_macros = "0.21"
+
 [dev-dependencies]
 flowy-test = { path = "../flowy-test" }

+ 1 - 5
rust-lib/flowy-document/src/event.rs

@@ -1,22 +1,18 @@
-use derive_more::Display;
 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 = "DocError"]
 pub enum EditorEvent {
-    #[display(fmt = "CreateDoc")]
     #[event(input = "CreateDocRequest", output = "DocInfo")]
     CreateDoc   = 0,
 
-    #[display(fmt = "UpdateDoc")]
     #[event(input = "UpdateDocRequest")]
     UpdateDoc   = 1,
 
-    #[display(fmt = "ReadDocInfo")]
     #[event(input = "QueryDocRequest", output = "DocInfo")]
     ReadDocInfo = 2,
 
-    #[display(fmt = "ReadDocData")]
     #[event(input = "QueryDocDataRequest", output = "DocData")]
     ReadDocData = 3,
 }

+ 5 - 5
rust-lib/flowy-document/tests/editor/helper.rs

@@ -1,4 +1,4 @@
-use flowy_test::builder::SingleUserTestBuilder;
+use flowy_test::builder::UserTestBuilder;
 
 use flowy_document::{entities::doc::*, event::EditorEvent::*};
 use flowy_infra::uuid;
@@ -11,7 +11,7 @@ pub fn create_doc(name: &str, desc: &str, text: &str) -> DocInfo {
         text: text.to_owned(),
     };
 
-    let doc_desc = SingleUserTestBuilder::new()
+    let doc_desc = UserTestBuilder::new()
         .event(CreateDoc)
         .request(request)
         .sync_send()
@@ -28,7 +28,7 @@ pub fn save_doc(desc: &DocInfo, content: &str) {
         text: Some(content.to_owned()),
     };
 
-    let _ = SingleUserTestBuilder::new()
+    let _ = UserTestBuilder::new()
         .event(UpdateDoc)
         .request(request)
         .sync_send();
@@ -40,7 +40,7 @@ pub fn read_doc(doc_id: &str) -> DocInfo {
         doc_id: doc_id.to_string(),
     };
 
-    let doc = SingleUserTestBuilder::new()
+    let doc = UserTestBuilder::new()
         .event(ReadDocInfo)
         .request(request)
         .sync_send()
@@ -55,7 +55,7 @@ pub fn read_doc_data(doc_id: &str, path: &str) -> DocData {
         path: path.to_string(),
     };
 
-    let doc = SingleUserTestBuilder::new()
+    let doc = UserTestBuilder::new()
         .event(ReadDocData)
         .request(request)
         .sync_send()

+ 3 - 3
rust-lib/flowy-sdk/src/deps_resolve/workspace_deps_impl.rs

@@ -2,7 +2,7 @@ use flowy_database::DBConnection;
 
 use flowy_user::prelude::UserSession;
 use flowy_workspace::{
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
     module::{WorkspaceDatabase, WorkspaceUser},
 };
 use std::sync::Arc;
@@ -14,7 +14,7 @@ pub struct WorkspaceUserImpl {
 impl WorkspaceUser for WorkspaceUserImpl {
     fn user_id(&self) -> Result<String, WorkspaceError> {
         self.user_session.user_id().map_err(|e| {
-            ErrorBuilder::new(WsErrCode::UserInternalError)
+            ErrorBuilder::new(ErrorCode::UserInternalError)
                 .error(e)
                 .build()
         })
@@ -28,7 +28,7 @@ pub struct WorkspaceDatabaseImpl {
 impl WorkspaceDatabase for WorkspaceDatabaseImpl {
     fn db_connection(&self) -> Result<DBConnection, WorkspaceError> {
         self.user_session.get_db_connection().map_err(|e| {
-            ErrorBuilder::new(WsErrCode::DatabaseConnectionFail)
+            ErrorBuilder::new(ErrorCode::DatabaseConnectionFail)
                 .error(e)
                 .build()
         })

+ 7 - 11
rust-lib/flowy-test/src/builder.rs

@@ -13,8 +13,8 @@ use flowy_user::errors::UserError;
 use flowy_workspace::errors::WorkspaceError;
 use std::marker::PhantomData;
 
-pub type SingleUserTestBuilder = TestBuilder<FixedUserTester<WorkspaceError>>;
-impl SingleUserTestBuilder {
+pub type UserTestBuilder = TestBuilder<FixedUserTester<WorkspaceError>>;
+impl UserTestBuilder {
     pub fn new() -> Self {
         let mut builder = TestBuilder::test(Box::new(FixedUserTester::<WorkspaceError>::new()));
         builder.setup_default_workspace();
@@ -27,13 +27,9 @@ impl SingleUserTestBuilder {
         let _ = create_default_workspace_if_need(&user_id);
     }
 }
-pub type UserTestBuilder = TestBuilder<RandomUserTester<UserError>>;
-impl UserTestBuilder {
-    pub fn new() -> Self {
-        let builder = TestBuilder::test(Box::new(RandomUserTester::<UserError>::new()));
-
-        builder
-    }
+pub type RandomUserTestBuilder = TestBuilder<RandomUserTester<UserError>>;
+impl RandomUserTestBuilder {
+    pub fn new() -> Self { TestBuilder::test(Box::new(RandomUserTester::<UserError>::new())) }
 
     pub fn reset(self) -> Self { self.login() }
 }
@@ -47,7 +43,7 @@ impl<T> TestBuilder<T>
 where
     T: TesterTrait,
 {
-    pub fn test(tester: Box<T>) -> Self {
+    fn test(tester: Box<T>) -> Self {
         Self {
             tester,
             user_detail: None,
@@ -60,7 +56,7 @@ where
         self
     }
 
-    pub fn login_if_need(&mut self) {
+    fn login_if_need(&mut self) {
         let user_detail = self.tester.login_if_need();
         self.user_detail = Some(user_detail);
     }

+ 4 - 4
rust-lib/flowy-test/src/helper.rs

@@ -1,7 +1,7 @@
 use bytes::Bytes;
 use flowy_dispatch::prelude::{DispatchError, EventDispatch, ModuleRequest, ToBytes};
 use flowy_infra::{kv::KVStore, uuid};
-use flowy_user::errors::{ErrorBuilder, UserErrCode, UserError};
+use flowy_user::errors::{ErrorBuilder, ErrorCode, UserError};
 use flowy_workspace::{
     entities::workspace::{CreateWorkspaceRequest, QueryWorkspaceRequest, Workspace},
     event::WorkspaceEvent::{CreateWorkspace, OpenWorkspace},
@@ -37,7 +37,7 @@ const DEFAULT_WORKSPACE: &'static str = "Default_Workspace";
 pub(crate) fn create_default_workspace_if_need(user_id: &str) -> Result<(), UserError> {
     let key = format!("{}{}", user_id, DEFAULT_WORKSPACE);
     if KVStore::get_bool(&key).unwrap_or(false) {
-        return Err(ErrorBuilder::new(UserErrCode::DefaultWorkspaceAlreadyExist).build());
+        return Err(ErrorBuilder::new(ErrorCode::DefaultWorkspaceAlreadyExist).build());
     }
     KVStore::set_bool(&key, true);
 
@@ -53,13 +53,13 @@ pub(crate) fn create_default_workspace_if_need(user_id: &str) -> Result<(), User
     let result = EventDispatch::sync_send(request)
         .parse::<Workspace, DispatchError>()
         .map_err(|e| {
-            ErrorBuilder::new(UserErrCode::CreateDefaultWorkspaceFailed)
+            ErrorBuilder::new(ErrorCode::CreateDefaultWorkspaceFailed)
                 .error(e)
                 .build()
         })?;
 
     let workspace = result.map_err(|e| {
-        ErrorBuilder::new(UserErrCode::CreateDefaultWorkspaceFailed)
+        ErrorBuilder::new(ErrorCode::CreateDefaultWorkspaceFailed)
             .error(e)
             .build()
     })?;

+ 4 - 1
rust-lib/flowy-test/src/tester.rs

@@ -9,6 +9,7 @@ use flowy_user::{
     event::UserEvent::{GetStatus, SignOut, SignUp},
     prelude::*,
 };
+use flowy_workspace::errors::ErrorCode;
 use std::{
     convert::TryFrom,
     fmt::{Debug, Display},
@@ -89,7 +90,9 @@ pub trait TesterTrait {
         let response = self.mut_context().response.clone().unwrap();
         match response.parse::<R, Self::Error>() {
             Ok(Ok(data)) => data,
-            Ok(Err(e)) => panic!("parse failed: {:?}", e),
+            Ok(Err(e)) => {
+                panic!("parse failed: {:?}", e)
+            },
             Err(e) => panic!("Internal error: {:?}", e),
         }
     }

+ 2 - 1
rust-lib/flowy-user/Cargo.toml

@@ -31,7 +31,8 @@ thread_local = "1.1.3"
 thread-id = "3.3.0"
 once_cell = "1.7.2"
 parking_lot = "0.11"
-
+strum = "0.21"
+strum_macros = "0.21"
 
 [dev-dependencies]
 quickcheck = "0.9.2"

+ 4 - 4
rust-lib/flowy-user/src/entities/parser/user_email.rs

@@ -1,19 +1,19 @@
-use crate::errors::UserErrCode;
+use crate::errors::ErrorCode;
 use validator::validate_email;
 
 #[derive(Debug)]
 pub struct UserEmail(pub String);
 
 impl UserEmail {
-    pub fn parse(s: String) -> Result<UserEmail, UserErrCode> {
+    pub fn parse(s: String) -> Result<UserEmail, ErrorCode> {
         if s.trim().is_empty() {
-            return Err(UserErrCode::EmailIsEmpty);
+            return Err(ErrorCode::EmailIsEmpty);
         }
 
         if validate_email(&s) {
             Ok(Self(s))
         } else {
-            Err(UserErrCode::EmailFormatInvalid)
+            Err(ErrorCode::EmailFormatInvalid)
         }
     }
 }

+ 5 - 5
rust-lib/flowy-user/src/entities/parser/user_name.rs

@@ -1,14 +1,14 @@
-use crate::errors::UserErrCode;
+use crate::errors::ErrorCode;
 use unicode_segmentation::UnicodeSegmentation;
 
 #[derive(Debug)]
 pub struct UserName(pub String);
 
 impl UserName {
-    pub fn parse(s: String) -> Result<UserName, UserErrCode> {
+    pub fn parse(s: String) -> Result<UserName, ErrorCode> {
         let is_empty_or_whitespace = s.trim().is_empty();
         if is_empty_or_whitespace {
-            return Err(UserErrCode::UserNameIsEmpty);
+            return Err(ErrorCode::UserNameIsEmpty);
         }
         // A grapheme is defined by the Unicode standard as a "user-perceived"
         // character: `å` is a single grapheme, but it is composed of two characters
@@ -19,14 +19,14 @@ impl UserName {
         // the recommended one.
         let is_too_long = s.graphemes(true).count() > 256;
         if is_too_long {
-            return Err(UserErrCode::UserNameTooLong);
+            return Err(ErrorCode::UserNameTooLong);
         }
 
         let forbidden_characters = ['/', '(', ')', '"', '<', '>', '\\', '{', '}'];
         let contains_forbidden_characters = s.chars().any(|g| forbidden_characters.contains(&g));
 
         if contains_forbidden_characters {
-            return Err(UserErrCode::UserNameContainsForbiddenCharacters);
+            return Err(ErrorCode::UserNameContainsForbiddenCharacters);
         }
 
         Ok(Self(s))

+ 6 - 6
rust-lib/flowy-user/src/entities/parser/user_password.rs

@@ -1,4 +1,4 @@
-use crate::errors::UserErrCode;
+use crate::errors::ErrorCode;
 use fancy_regex::Regex;
 use lazy_static::lazy_static;
 use unicode_segmentation::UnicodeSegmentation;
@@ -7,23 +7,23 @@ use unicode_segmentation::UnicodeSegmentation;
 pub struct UserPassword(pub String);
 
 impl UserPassword {
-    pub fn parse(s: String) -> Result<UserPassword, UserErrCode> {
+    pub fn parse(s: String) -> Result<UserPassword, ErrorCode> {
         if s.trim().is_empty() {
-            return Err(UserErrCode::PasswordIsEmpty);
+            return Err(ErrorCode::PasswordIsEmpty);
         }
 
         if s.graphemes(true).count() > 100 {
-            return Err(UserErrCode::PasswordTooLong);
+            return Err(ErrorCode::PasswordTooLong);
         }
 
         let forbidden_characters = ['/', '(', ')', '"', '<', '>', '\\', '{', '}'];
         let contains_forbidden_characters = s.chars().any(|g| forbidden_characters.contains(&g));
         if contains_forbidden_characters {
-            return Err(UserErrCode::PasswordContainsForbidCharacters);
+            return Err(ErrorCode::PasswordContainsForbidCharacters);
         }
 
         if !validate_password(&s) {
-            return Err(UserErrCode::PasswordFormatInvalid);
+            return Err(ErrorCode::PasswordFormatInvalid);
         }
 
         Ok(Self(s))

+ 2 - 2
rust-lib/flowy-user/src/entities/user_update.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::parser::*,
-    errors::{ErrorBuilder, UserErrCode, UserError},
+    errors::{ErrorBuilder, ErrorCode, UserError},
 };
 use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
@@ -64,7 +64,7 @@ impl TryInto<UpdateUserParams> for UpdateUserRequest {
 
     fn try_into(self) -> Result<UpdateUserParams, Self::Error> {
         let id = UserId::parse(self.id)
-            .map_err(|e| ErrorBuilder::new(UserErrCode::UserIdInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::UserIdInvalid).msg(e).build())?
             .0;
 
         let name = match self.name {

+ 13 - 13
rust-lib/flowy-user/src/errors.rs

@@ -10,14 +10,14 @@ use std::{
 #[derive(Debug, Default, Clone, ProtoBuf)]
 pub struct UserError {
     #[pb(index = 1)]
-    pub code: UserErrCode,
+    pub code: ErrorCode,
 
     #[pb(index = 2)]
     pub msg: String,
 }
 
 impl UserError {
-    fn new(code: UserErrCode, msg: &str) -> Self {
+    fn new(code: ErrorCode, msg: &str) -> Self {
         Self {
             code,
             msg: msg.to_owned(),
@@ -26,7 +26,7 @@ impl UserError {
 }
 
 #[derive(Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
-pub enum UserErrCode {
+pub enum ErrorCode {
     #[display(fmt = "Unknown")]
     Unknown              = 0,
     #[display(fmt = "Database init failed")]
@@ -87,21 +87,21 @@ pub enum UserErrCode {
     ServerError          = 100,
 }
 
-impl Debug for UserErrCode {
+impl Debug for ErrorCode {
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&format!("{}", self)) }
 }
 
-impl UserErrCode {
+impl ErrorCode {
     pub fn to_string(&self) -> String { format!("{}", self) }
 }
 
-impl std::default::Default for UserErrCode {
-    fn default() -> Self { UserErrCode::Unknown }
+impl std::default::Default for ErrorCode {
+    fn default() -> Self { ErrorCode::Unknown }
 }
 
 impl std::convert::From<flowy_database::result::Error> for UserError {
     fn from(error: flowy_database::result::Error) -> Self {
-        ErrorBuilder::new(UserErrCode::UserDatabaseInternalError)
+        ErrorBuilder::new(ErrorCode::UserDatabaseInternalError)
             .error(error)
             .build()
     }
@@ -138,7 +138,7 @@ impl std::convert::From<flowy_sqlite::Error> for UserError {
         //     ErrorKind::__Nonexhaustive { .. } => {},
         // }
 
-        ErrorBuilder::new(UserErrCode::SqlInternalError)
+        ErrorBuilder::new(ErrorCode::SqlInternalError)
             .error(error)
             .build()
     }
@@ -146,7 +146,7 @@ impl std::convert::From<flowy_sqlite::Error> for UserError {
 
 impl std::convert::From<flowy_net::errors::ServerError> for UserError {
     fn from(error: flowy_net::errors::ServerError) -> Self {
-        ErrorBuilder::new(UserErrCode::ServerError)
+        ErrorBuilder::new(ErrorCode::ServerError)
             .error(error.msg)
             .build()
     }
@@ -159,10 +159,10 @@ impl flowy_dispatch::Error for UserError {
     }
 }
 
-pub type ErrorBuilder = flowy_infra::errors::Builder<UserErrCode, UserError>;
+pub type ErrorBuilder = flowy_infra::errors::Builder<ErrorCode, UserError>;
 
-impl flowy_infra::errors::Build<UserErrCode> for UserError {
-    fn build(code: UserErrCode, msg: String) -> Self {
+impl flowy_infra::errors::Build<ErrorCode> for UserError {
+    fn build(code: ErrorCode, msg: String) -> Self {
         let msg = if msg.is_empty() {
             format!("{}", code)
         } else {

+ 5 - 6
rust-lib/flowy-user/src/event.rs

@@ -1,22 +1,21 @@
-use derive_more::Display;
 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 = "UserError"]
 pub enum UserEvent {
-    #[display(fmt = "GetStatus")]
     #[event(output = "UserDetail")]
     GetStatus  = 0,
-    #[display(fmt = "SignIn")]
+
     #[event(input = "SignInRequest", output = "UserDetail")]
     SignIn     = 1,
-    #[display(fmt = "SignUp")]
+
     #[event(input = "SignUpRequest", output = "UserDetail")]
     SignUp     = 2,
-    #[display(fmt = "SignOut")]
+
     #[event(passthrough)]
     SignOut    = 3,
-    #[display(fmt = "UpdateUser")]
+
     #[event(input = "UpdateUserRequest", output = "UserDetail")]
     UpdateUser = 4,
 }

+ 85 - 85
rust-lib/flowy-user/src/protobuf/model/errors.rs

@@ -26,7 +26,7 @@
 #[derive(PartialEq,Clone,Default)]
 pub struct UserError {
     // message fields
-    pub code: UserErrCode,
+    pub code: ErrorCode,
     pub msg: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
@@ -44,18 +44,18 @@ impl UserError {
         ::std::default::Default::default()
     }
 
-    // .UserErrCode code = 1;
+    // .ErrorCode code = 1;
 
 
-    pub fn get_code(&self) -> UserErrCode {
+    pub fn get_code(&self) -> ErrorCode {
         self.code
     }
     pub fn clear_code(&mut self) {
-        self.code = UserErrCode::Unknown;
+        self.code = ErrorCode::Unknown;
     }
 
     // Param is passed by value, moved
-    pub fn set_code(&mut self, v: UserErrCode) {
+    pub fn set_code(&mut self, v: ErrorCode) {
         self.code = v;
     }
 
@@ -113,7 +113,7 @@ impl ::protobuf::Message for UserError {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if self.code != UserErrCode::Unknown {
+        if self.code != ErrorCode::Unknown {
             my_size += ::protobuf::rt::enum_size(1, self.code);
         }
         if !self.msg.is_empty() {
@@ -125,7 +125,7 @@ impl ::protobuf::Message for UserError {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if self.code != UserErrCode::Unknown {
+        if self.code != ErrorCode::Unknown {
             os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.code))?;
         }
         if !self.msg.is_empty() {
@@ -169,7 +169,7 @@ impl ::protobuf::Message for UserError {
         static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
         descriptor.get(|| {
             let mut fields = ::std::vec::Vec::new();
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<UserErrCode>>(
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ErrorCode>>(
                 "code",
                 |m: &UserError| { &m.code },
                 |m: &mut UserError| { &mut m.code },
@@ -195,7 +195,7 @@ impl ::protobuf::Message for UserError {
 
 impl ::protobuf::Clear for UserError {
     fn clear(&mut self) {
-        self.code = UserErrCode::Unknown;
+        self.code = ErrorCode::Unknown;
         self.msg.clear();
         self.unknown_fields.clear();
     }
@@ -214,7 +214,7 @@ impl ::protobuf::reflect::ProtobufValue for UserError {
 }
 
 #[derive(Clone,PartialEq,Eq,Debug,Hash)]
-pub enum UserErrCode {
+pub enum ErrorCode {
     Unknown = 0,
     UserDatabaseInitFailed = 1,
     UserDatabaseWriteLocked = 2,
@@ -242,69 +242,69 @@ pub enum UserErrCode {
     ServerError = 100,
 }
 
-impl ::protobuf::ProtobufEnum for UserErrCode {
+impl ::protobuf::ProtobufEnum for ErrorCode {
     fn value(&self) -> i32 {
         *self as i32
     }
 
-    fn from_i32(value: i32) -> ::std::option::Option<UserErrCode> {
+    fn from_i32(value: i32) -> ::std::option::Option<ErrorCode> {
         match value {
-            0 => ::std::option::Option::Some(UserErrCode::Unknown),
-            1 => ::std::option::Option::Some(UserErrCode::UserDatabaseInitFailed),
-            2 => ::std::option::Option::Some(UserErrCode::UserDatabaseWriteLocked),
-            3 => ::std::option::Option::Some(UserErrCode::UserDatabaseReadLocked),
-            4 => ::std::option::Option::Some(UserErrCode::UserDatabaseDidNotMatch),
-            5 => ::std::option::Option::Some(UserErrCode::UserDatabaseInternalError),
-            6 => ::std::option::Option::Some(UserErrCode::SqlInternalError),
-            10 => ::std::option::Option::Some(UserErrCode::UserNotLoginYet),
-            11 => ::std::option::Option::Some(UserErrCode::ReadCurrentIdFailed),
-            12 => ::std::option::Option::Some(UserErrCode::WriteCurrentIdFailed),
-            20 => ::std::option::Option::Some(UserErrCode::EmailIsEmpty),
-            21 => ::std::option::Option::Some(UserErrCode::EmailFormatInvalid),
-            22 => ::std::option::Option::Some(UserErrCode::EmailAlreadyExists),
-            30 => ::std::option::Option::Some(UserErrCode::PasswordIsEmpty),
-            31 => ::std::option::Option::Some(UserErrCode::PasswordTooLong),
-            32 => ::std::option::Option::Some(UserErrCode::PasswordContainsForbidCharacters),
-            33 => ::std::option::Option::Some(UserErrCode::PasswordFormatInvalid),
-            40 => ::std::option::Option::Some(UserErrCode::UserNameTooLong),
-            41 => ::std::option::Option::Some(UserErrCode::UserNameContainsForbiddenCharacters),
-            42 => ::std::option::Option::Some(UserErrCode::UserNameIsEmpty),
-            50 => ::std::option::Option::Some(UserErrCode::UserWorkspaceInvalid),
-            51 => ::std::option::Option::Some(UserErrCode::UserIdInvalid),
-            52 => ::std::option::Option::Some(UserErrCode::CreateDefaultWorkspaceFailed),
-            53 => ::std::option::Option::Some(UserErrCode::DefaultWorkspaceAlreadyExist),
-            100 => ::std::option::Option::Some(UserErrCode::ServerError),
+            0 => ::std::option::Option::Some(ErrorCode::Unknown),
+            1 => ::std::option::Option::Some(ErrorCode::UserDatabaseInitFailed),
+            2 => ::std::option::Option::Some(ErrorCode::UserDatabaseWriteLocked),
+            3 => ::std::option::Option::Some(ErrorCode::UserDatabaseReadLocked),
+            4 => ::std::option::Option::Some(ErrorCode::UserDatabaseDidNotMatch),
+            5 => ::std::option::Option::Some(ErrorCode::UserDatabaseInternalError),
+            6 => ::std::option::Option::Some(ErrorCode::SqlInternalError),
+            10 => ::std::option::Option::Some(ErrorCode::UserNotLoginYet),
+            11 => ::std::option::Option::Some(ErrorCode::ReadCurrentIdFailed),
+            12 => ::std::option::Option::Some(ErrorCode::WriteCurrentIdFailed),
+            20 => ::std::option::Option::Some(ErrorCode::EmailIsEmpty),
+            21 => ::std::option::Option::Some(ErrorCode::EmailFormatInvalid),
+            22 => ::std::option::Option::Some(ErrorCode::EmailAlreadyExists),
+            30 => ::std::option::Option::Some(ErrorCode::PasswordIsEmpty),
+            31 => ::std::option::Option::Some(ErrorCode::PasswordTooLong),
+            32 => ::std::option::Option::Some(ErrorCode::PasswordContainsForbidCharacters),
+            33 => ::std::option::Option::Some(ErrorCode::PasswordFormatInvalid),
+            40 => ::std::option::Option::Some(ErrorCode::UserNameTooLong),
+            41 => ::std::option::Option::Some(ErrorCode::UserNameContainsForbiddenCharacters),
+            42 => ::std::option::Option::Some(ErrorCode::UserNameIsEmpty),
+            50 => ::std::option::Option::Some(ErrorCode::UserWorkspaceInvalid),
+            51 => ::std::option::Option::Some(ErrorCode::UserIdInvalid),
+            52 => ::std::option::Option::Some(ErrorCode::CreateDefaultWorkspaceFailed),
+            53 => ::std::option::Option::Some(ErrorCode::DefaultWorkspaceAlreadyExist),
+            100 => ::std::option::Option::Some(ErrorCode::ServerError),
             _ => ::std::option::Option::None
         }
     }
 
     fn values() -> &'static [Self] {
-        static values: &'static [UserErrCode] = &[
-            UserErrCode::Unknown,
-            UserErrCode::UserDatabaseInitFailed,
-            UserErrCode::UserDatabaseWriteLocked,
-            UserErrCode::UserDatabaseReadLocked,
-            UserErrCode::UserDatabaseDidNotMatch,
-            UserErrCode::UserDatabaseInternalError,
-            UserErrCode::SqlInternalError,
-            UserErrCode::UserNotLoginYet,
-            UserErrCode::ReadCurrentIdFailed,
-            UserErrCode::WriteCurrentIdFailed,
-            UserErrCode::EmailIsEmpty,
-            UserErrCode::EmailFormatInvalid,
-            UserErrCode::EmailAlreadyExists,
-            UserErrCode::PasswordIsEmpty,
-            UserErrCode::PasswordTooLong,
-            UserErrCode::PasswordContainsForbidCharacters,
-            UserErrCode::PasswordFormatInvalid,
-            UserErrCode::UserNameTooLong,
-            UserErrCode::UserNameContainsForbiddenCharacters,
-            UserErrCode::UserNameIsEmpty,
-            UserErrCode::UserWorkspaceInvalid,
-            UserErrCode::UserIdInvalid,
-            UserErrCode::CreateDefaultWorkspaceFailed,
-            UserErrCode::DefaultWorkspaceAlreadyExist,
-            UserErrCode::ServerError,
+        static values: &'static [ErrorCode] = &[
+            ErrorCode::Unknown,
+            ErrorCode::UserDatabaseInitFailed,
+            ErrorCode::UserDatabaseWriteLocked,
+            ErrorCode::UserDatabaseReadLocked,
+            ErrorCode::UserDatabaseDidNotMatch,
+            ErrorCode::UserDatabaseInternalError,
+            ErrorCode::SqlInternalError,
+            ErrorCode::UserNotLoginYet,
+            ErrorCode::ReadCurrentIdFailed,
+            ErrorCode::WriteCurrentIdFailed,
+            ErrorCode::EmailIsEmpty,
+            ErrorCode::EmailFormatInvalid,
+            ErrorCode::EmailAlreadyExists,
+            ErrorCode::PasswordIsEmpty,
+            ErrorCode::PasswordTooLong,
+            ErrorCode::PasswordContainsForbidCharacters,
+            ErrorCode::PasswordFormatInvalid,
+            ErrorCode::UserNameTooLong,
+            ErrorCode::UserNameContainsForbiddenCharacters,
+            ErrorCode::UserNameIsEmpty,
+            ErrorCode::UserWorkspaceInvalid,
+            ErrorCode::UserIdInvalid,
+            ErrorCode::CreateDefaultWorkspaceFailed,
+            ErrorCode::DefaultWorkspaceAlreadyExist,
+            ErrorCode::ServerError,
         ];
         values
     }
@@ -312,52 +312,52 @@ impl ::protobuf::ProtobufEnum for UserErrCode {
     fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
         static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
         descriptor.get(|| {
-            ::protobuf::reflect::EnumDescriptor::new_pb_name::<UserErrCode>("UserErrCode", file_descriptor_proto())
+            ::protobuf::reflect::EnumDescriptor::new_pb_name::<ErrorCode>("ErrorCode", file_descriptor_proto())
         })
     }
 }
 
-impl ::std::marker::Copy for UserErrCode {
+impl ::std::marker::Copy for ErrorCode {
 }
 
-impl ::std::default::Default for UserErrCode {
+impl ::std::default::Default for ErrorCode {
     fn default() -> Self {
-        UserErrCode::Unknown
+        ErrorCode::Unknown
     }
 }
 
-impl ::protobuf::reflect::ProtobufValue for UserErrCode {
+impl ::protobuf::reflect::ProtobufValue for ErrorCode {
     fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
         ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
     }
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x0cerrors.proto\"?\n\tUserError\x12\x20\n\x04code\x18\x01\x20\x01(\
-    \x0e2\x0c.UserErrCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03m\
-    sg*\x8b\x05\n\x0bUserErrCode\x12\x0b\n\x07Unknown\x10\0\x12\x1a\n\x16Use\
-    rDatabaseInitFailed\x10\x01\x12\x1b\n\x17UserDatabaseWriteLocked\x10\x02\
-    \x12\x1a\n\x16UserDatabaseReadLocked\x10\x03\x12\x1b\n\x17UserDatabaseDi\
-    dNotMatch\x10\x04\x12\x1d\n\x19UserDatabaseInternalError\x10\x05\x12\x14\
-    \n\x10SqlInternalError\x10\x06\x12\x13\n\x0fUserNotLoginYet\x10\n\x12\
-    \x17\n\x13ReadCurrentIdFailed\x10\x0b\x12\x18\n\x14WriteCurrentIdFailed\
-    \x10\x0c\x12\x10\n\x0cEmailIsEmpty\x10\x14\x12\x16\n\x12EmailFormatInval\
-    id\x10\x15\x12\x16\n\x12EmailAlreadyExists\x10\x16\x12\x13\n\x0fPassword\
-    IsEmpty\x10\x1e\x12\x13\n\x0fPasswordTooLong\x10\x1f\x12$\n\x20PasswordC\
-    ontainsForbidCharacters\x10\x20\x12\x19\n\x15PasswordFormatInvalid\x10!\
+    \n\x0cerrors.proto\"=\n\tUserError\x12\x1e\n\x04code\x18\x01\x20\x01(\
+    \x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\
+    \x89\x05\n\tErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x1a\n\x16UserDataba\
+    seInitFailed\x10\x01\x12\x1b\n\x17UserDatabaseWriteLocked\x10\x02\x12\
+    \x1a\n\x16UserDatabaseReadLocked\x10\x03\x12\x1b\n\x17UserDatabaseDidNot\
+    Match\x10\x04\x12\x1d\n\x19UserDatabaseInternalError\x10\x05\x12\x14\n\
+    \x10SqlInternalError\x10\x06\x12\x13\n\x0fUserNotLoginYet\x10\n\x12\x17\
+    \n\x13ReadCurrentIdFailed\x10\x0b\x12\x18\n\x14WriteCurrentIdFailed\x10\
+    \x0c\x12\x10\n\x0cEmailIsEmpty\x10\x14\x12\x16\n\x12EmailFormatInvalid\
+    \x10\x15\x12\x16\n\x12EmailAlreadyExists\x10\x16\x12\x13\n\x0fPasswordIs\
+    Empty\x10\x1e\x12\x13\n\x0fPasswordTooLong\x10\x1f\x12$\n\x20PasswordCon\
+    tainsForbidCharacters\x10\x20\x12\x19\n\x15PasswordFormatInvalid\x10!\
     \x12\x13\n\x0fUserNameTooLong\x10(\x12'\n#UserNameContainsForbiddenChara\
     cters\x10)\x12\x13\n\x0fUserNameIsEmpty\x10*\x12\x18\n\x14UserWorkspaceI\
     nvalid\x102\x12\x11\n\rUserIdInvalid\x103\x12\x20\n\x1cCreateDefaultWork\
     spaceFailed\x104\x12\x20\n\x1cDefaultWorkspaceAlreadyExist\x105\x12\x0f\
     \n\x0bServerError\x10dJ\xb1\t\n\x06\x12\x04\0\0\x20\x01\n\x08\n\x01\x0c\
     \x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\
-    \x01\x12\x03\x02\x08\x11\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x19\n\
-    \x0c\n\x05\x04\0\x02\0\x06\x12\x03\x03\x04\x0f\n\x0c\n\x05\x04\0\x02\0\
-    \x01\x12\x03\x03\x10\x14\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x17\x18\
-    \n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\
+    \x01\x12\x03\x02\x08\x11\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x17\n\
+    \x0c\n\x05\x04\0\x02\0\x06\x12\x03\x03\x04\r\n\x0c\n\x05\x04\0\x02\0\x01\
+    \x12\x03\x03\x0e\x12\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x15\x16\n\
+    \x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\
     \x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\
     \n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\0\x12\
-    \x04\x06\0\x20\x01\n\n\n\x03\x05\0\x01\x12\x03\x06\x05\x10\n\x0b\n\x04\
+    \x04\x06\0\x20\x01\n\n\n\x03\x05\0\x01\x12\x03\x06\x05\x0e\n\x0b\n\x04\
     \x05\0\x02\0\x12\x03\x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\
     \x04\x0b\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x07\x0e\x0f\n\x0b\n\x04\x05\
     \0\x02\x01\x12\x03\x08\x04\x1f\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\

+ 2 - 2
rust-lib/flowy-user/src/protobuf/proto/errors.proto

@@ -1,10 +1,10 @@
 syntax = "proto3";
 
 message UserError {
-    UserErrCode code = 1;
+    ErrorCode code = 1;
     string msg = 2;
 }
-enum UserErrCode {
+enum ErrorCode {
     Unknown = 0;
     UserDatabaseInitFailed = 1;
     UserDatabaseWriteLocked = 2;

+ 7 - 7
rust-lib/flowy-user/src/services/user/database.rs

@@ -1,4 +1,4 @@
-use crate::errors::{ErrorBuilder, UserErrCode, UserError};
+use crate::errors::{ErrorBuilder, ErrorCode, UserError};
 use flowy_database::{DBConnection, Database};
 use lazy_static::lazy_static;
 use once_cell::sync::Lazy;
@@ -22,7 +22,7 @@ impl UserDB {
 
     fn open_user_db(&self, user_id: &str) -> Result<(), UserError> {
         if user_id.is_empty() {
-            return Err(ErrorBuilder::new(UserErrCode::UserDatabaseInitFailed)
+            return Err(ErrorBuilder::new(ErrorCode::UserDatabaseInitFailed)
                 .msg("user id is empty")
                 .build());
         }
@@ -30,13 +30,13 @@ impl UserDB {
         let dir = format!("{}/{}", self.db_dir, user_id);
         let db = flowy_database::init(&dir).map_err(|e| {
             log::error!("flowy_database::init failed, {:?}", e);
-            ErrorBuilder::new(UserErrCode::UserDatabaseInitFailed)
+            ErrorBuilder::new(ErrorCode::UserDatabaseInitFailed)
                 .error(e)
                 .build()
         })?;
 
         let mut db_map = DB_MAP.write().map_err(|e| {
-            ErrorBuilder::new(UserErrCode::UserDatabaseWriteLocked)
+            ErrorBuilder::new(ErrorCode::UserDatabaseWriteLocked)
                 .error(e)
                 .build()
         })?;
@@ -47,7 +47,7 @@ impl UserDB {
 
     pub(crate) fn close_user_db(&self, user_id: &str) -> Result<(), UserError> {
         let mut db_map = DB_MAP.write().map_err(|e| {
-            ErrorBuilder::new(UserErrCode::UserDatabaseWriteLocked)
+            ErrorBuilder::new(ErrorCode::UserDatabaseWriteLocked)
                 .msg(format!("Close user db failed. {:?}", e))
                 .build()
         })?;
@@ -63,13 +63,13 @@ impl UserDB {
         }
 
         let db_map = DB_MAP.read().map_err(|e| {
-            ErrorBuilder::new(UserErrCode::UserDatabaseReadLocked)
+            ErrorBuilder::new(ErrorCode::UserDatabaseReadLocked)
                 .error(e)
                 .build()
         })?;
 
         match db_map.get(user_id) {
-            None => Err(ErrorBuilder::new(UserErrCode::UserDatabaseInitFailed)
+            None => Err(ErrorBuilder::new(ErrorCode::UserDatabaseInitFailed)
                 .msg("Get connection failed. The database is not initialization")
                 .build()),
             Some(database) => Ok(database.get_connection()?),

+ 3 - 3
rust-lib/flowy-user/src/services/user/user_server/server_api.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UserDetail},
-    errors::{ErrorBuilder, UserErrCode, UserError},
+    errors::{ErrorBuilder, ErrorCode, UserError},
 };
 
 use flowy_net::{config::*, future::ResultFuture, request::HttpRequestBuilder};
@@ -27,11 +27,11 @@ impl UserServerAPI for UserServer {
     }
 
     fn sign_out(&self, _user_id: &str) -> ResultFuture<(), UserError> {
-        ResultFuture::new(async { Err(ErrorBuilder::new(UserErrCode::Unknown).build()) })
+        ResultFuture::new(async { Err(ErrorBuilder::new(ErrorCode::Unknown).build()) })
     }
 
     fn get_user_info(&self, _user_id: &str) -> ResultFuture<UserDetail, UserError> {
-        ResultFuture::new(async { Err(ErrorBuilder::new(UserErrCode::Unknown).build()) })
+        ResultFuture::new(async { Err(ErrorBuilder::new(ErrorCode::Unknown).build()) })
     }
 }
 

+ 2 - 2
rust-lib/flowy-user/src/services/user/user_server/server_api_mock.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UserDetail},
-    errors::{ErrorBuilder, UserErrCode, UserError},
+    errors::{ErrorBuilder, ErrorCode, UserError},
     services::user::UserServerAPI,
 };
 
@@ -44,6 +44,6 @@ impl UserServerAPI for UserServerMock {
     }
 
     fn get_user_info(&self, _user_id: &str) -> ResultFuture<UserDetail, UserError> {
-        ResultFuture::new(async { Err(ErrorBuilder::new(UserErrCode::Unknown).build()) })
+        ResultFuture::new(async { Err(ErrorBuilder::new(ErrorCode::Unknown).build()) })
     }
 }

+ 5 - 5
rust-lib/flowy-user/src/services/user/user_session.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::{SignInParams, SignUpParams, UpdateUserParams, UserDetail},
-    errors::{ErrorBuilder, UserErrCode, UserError},
+    errors::{ErrorBuilder, ErrorCode, UserError},
     services::{
         user::{construct_user_server, database::UserDB, UserServerAPI},
         workspace::UserWorkspaceController,
@@ -124,7 +124,7 @@ impl UserSession {
                 *write_guard = user_id;
                 Ok(())
             },
-            Err(e) => Err(ErrorBuilder::new(UserErrCode::WriteCurrentIdFailed)
+            Err(e) => Err(ErrorBuilder::new(ErrorCode::WriteCurrentIdFailed)
                 .error(e)
                 .build()),
         }
@@ -138,7 +138,7 @@ impl UserSession {
     pub fn user_id(&self) -> Result<String, UserError> {
         let mut user_id = {
             let read_guard = self.user_id.read().map_err(|e| {
-                ErrorBuilder::new(UserErrCode::ReadCurrentIdFailed)
+                ErrorBuilder::new(ErrorCode::ReadCurrentIdFailed)
                     .error(e)
                     .build()
             })?;
@@ -152,7 +152,7 @@ impl UserSession {
         }
 
         match user_id {
-            None => Err(ErrorBuilder::new(UserErrCode::UserNotLoginYet).build()),
+            None => Err(ErrorBuilder::new(ErrorCode::UserNotLoginYet).build()),
             Some(user_id) => Ok(user_id),
         }
     }
@@ -160,7 +160,7 @@ impl UserSession {
 
 pub fn current_user_id() -> Result<String, UserError> {
     match KVStore::get_str(USER_ID_CACHE_KEY) {
-        None => Err(ErrorBuilder::new(UserErrCode::UserNotLoginYet).build()),
+        None => Err(ErrorBuilder::new(ErrorCode::UserNotLoginYet).build()),
         Some(user_id) => Ok(user_id),
     }
 }

+ 1 - 1
rust-lib/flowy-user/tests/event/helper.rs

@@ -1,4 +1,4 @@
-pub use flowy_test::builder::UserTestBuilder;
+pub use flowy_test::builder::RandomUserTestBuilder;
 
 pub use flowy_test::prelude::{random_valid_email, valid_password};
 

+ 5 - 5
rust-lib/flowy-user/tests/event/sign_in_test.rs

@@ -1,5 +1,5 @@
 use crate::helper::*;
-use flowy_user::{errors::UserErrCode, event::UserEvent::*, prelude::*};
+use flowy_user::{errors::ErrorCode, event::UserEvent::*, prelude::*};
 use serial_test::*;
 
 #[test]
@@ -10,7 +10,7 @@ fn sign_in_success() {
         password: valid_password(),
     };
 
-    let response = UserTestBuilder::new()
+    let response = RandomUserTestBuilder::new()
         .logout()
         .event(SignIn)
         .request(request)
@@ -29,13 +29,13 @@ fn sign_in_with_invalid_email() {
         };
 
         assert_eq!(
-            UserTestBuilder::new()
+            RandomUserTestBuilder::new()
                 .event(SignIn)
                 .request(request)
                 .sync_send()
                 .error()
                 .code,
-            UserErrCode::EmailFormatInvalid
+            ErrorCode::EmailFormatInvalid
         );
     }
 }
@@ -49,7 +49,7 @@ fn sign_in_with_invalid_password() {
             password,
         };
 
-        UserTestBuilder::new()
+        RandomUserTestBuilder::new()
             .event(SignIn)
             .request(request)
             .sync_send()

+ 4 - 4
rust-lib/flowy-user/tests/event/sign_up_test.rs

@@ -11,7 +11,7 @@ fn sign_up_success() {
         password: valid_password(),
     };
 
-    let _response = UserTestBuilder::new()
+    let _response = RandomUserTestBuilder::new()
         .logout()
         .event(SignUp)
         .request(request)
@@ -29,13 +29,13 @@ fn sign_up_with_invalid_email() {
         };
 
         assert_eq!(
-            UserTestBuilder::new()
+            RandomUserTestBuilder::new()
                 .event(SignUp)
                 .request(request)
                 .sync_send()
                 .error()
                 .code,
-            UserErrCode::EmailFormatInvalid
+            ErrorCode::EmailFormatInvalid
         );
     }
 }
@@ -49,7 +49,7 @@ fn sign_up_with_invalid_password() {
             password,
         };
 
-        UserTestBuilder::new()
+        RandomUserTestBuilder::new()
             .event(SignUp)
             .request(request)
             .sync_send()

+ 3 - 3
rust-lib/flowy-user/tests/event/user_status_test.rs

@@ -5,7 +5,7 @@ use serial_test::*;
 #[test]
 #[serial]
 fn user_status_get_failed_before_login() {
-    let _a = UserTestBuilder::new()
+    let _a = RandomUserTestBuilder::new()
         .logout()
         .event(GetStatus)
         .assert_error()
@@ -20,7 +20,7 @@ fn user_status_get_success_after_login() {
         password: valid_password(),
     };
 
-    let response = UserTestBuilder::new()
+    let response = RandomUserTestBuilder::new()
         .logout()
         .event(SignIn)
         .request(request)
@@ -28,7 +28,7 @@ fn user_status_get_success_after_login() {
         .parse::<UserDetail>();
     dbg!(&response);
 
-    let _ = UserTestBuilder::new()
+    let _ = RandomUserTestBuilder::new()
         .event(GetStatus)
         .sync_send()
         .parse::<UserDetail>();

+ 14 - 14
rust-lib/flowy-user/tests/event/user_update_test.rs

@@ -1,11 +1,11 @@
 use crate::helper::*;
-use flowy_user::{errors::UserErrCode, event::UserEvent::*, prelude::*};
+use flowy_user::{errors::ErrorCode, event::UserEvent::*, prelude::*};
 use serial_test::*;
 
 #[test]
 #[serial]
 fn user_update_with_name() {
-    let user_detail = UserTestBuilder::new().reset().user_detail.unwrap();
+    let user_detail = RandomUserTestBuilder::new().reset().user_detail.unwrap();
     let new_name = "hello_world".to_owned();
     let request = UpdateUserRequest {
         id: user_detail.id.clone(),
@@ -14,7 +14,7 @@ fn user_update_with_name() {
         password: None,
     };
 
-    let user_detail = UserTestBuilder::new()
+    let user_detail = RandomUserTestBuilder::new()
         .event(UpdateUser)
         .request(request)
         .sync_send()
@@ -26,7 +26,7 @@ fn user_update_with_name() {
 #[test]
 #[serial]
 fn user_update_with_email() {
-    let user_detail = UserTestBuilder::new().reset().user_detail.unwrap();
+    let user_detail = RandomUserTestBuilder::new().reset().user_detail.unwrap();
     let new_email = "[email protected]".to_owned();
     let request = UpdateUserRequest {
         id: user_detail.id.clone(),
@@ -35,7 +35,7 @@ fn user_update_with_email() {
         password: None,
     };
 
-    let user_detail = UserTestBuilder::new()
+    let user_detail = RandomUserTestBuilder::new()
         .event(UpdateUser)
         .request(request)
         .sync_send()
@@ -47,7 +47,7 @@ fn user_update_with_email() {
 #[test]
 #[serial]
 fn user_update_with_password() {
-    let user_detail = UserTestBuilder::new().reset().user_detail.unwrap();
+    let user_detail = RandomUserTestBuilder::new().reset().user_detail.unwrap();
     let new_password = "H123world!".to_owned();
     let request = UpdateUserRequest {
         id: user_detail.id.clone(),
@@ -56,7 +56,7 @@ fn user_update_with_password() {
         password: Some(new_password.clone()),
     };
 
-    let _ = UserTestBuilder::new()
+    let _ = RandomUserTestBuilder::new()
         .event(UpdateUser)
         .request(request)
         .sync_send()
@@ -66,7 +66,7 @@ fn user_update_with_password() {
 #[test]
 #[serial]
 fn user_update_with_invalid_email() {
-    let user_detail = UserTestBuilder::new().reset().user_detail.unwrap();
+    let user_detail = RandomUserTestBuilder::new().reset().user_detail.unwrap();
     for email in invalid_email_test_case() {
         let request = UpdateUserRequest {
             id: user_detail.id.clone(),
@@ -76,13 +76,13 @@ fn user_update_with_invalid_email() {
         };
 
         assert_eq!(
-            UserTestBuilder::new()
+            RandomUserTestBuilder::new()
                 .event(UpdateUser)
                 .request(request)
                 .sync_send()
                 .error()
                 .code,
-            UserErrCode::EmailFormatInvalid
+            ErrorCode::EmailFormatInvalid
         );
     }
 }
@@ -90,7 +90,7 @@ fn user_update_with_invalid_email() {
 #[test]
 #[serial]
 fn user_update_with_invalid_password() {
-    let user_detail = UserTestBuilder::new().reset().user_detail.unwrap();
+    let user_detail = RandomUserTestBuilder::new().reset().user_detail.unwrap();
     for password in invalid_password_test_case() {
         let request = UpdateUserRequest {
             id: user_detail.id.clone(),
@@ -99,7 +99,7 @@ fn user_update_with_invalid_password() {
             password: Some(password),
         };
 
-        UserTestBuilder::new()
+        RandomUserTestBuilder::new()
             .event(UpdateUser)
             .request(request)
             .sync_send()
@@ -110,7 +110,7 @@ fn user_update_with_invalid_password() {
 #[test]
 #[serial]
 fn user_update_with_invalid_name() {
-    let user_detail = UserTestBuilder::new().reset().user_detail.unwrap();
+    let user_detail = RandomUserTestBuilder::new().reset().user_detail.unwrap();
     let request = UpdateUserRequest {
         id: user_detail.id.clone(),
         name: Some("".to_string()),
@@ -118,7 +118,7 @@ fn user_update_with_invalid_name() {
         password: None,
     };
 
-    UserTestBuilder::new()
+    RandomUserTestBuilder::new()
         .event(UpdateUser)
         .request(request)
         .sync_send()

+ 2 - 0
rust-lib/flowy-workspace/Cargo.toml

@@ -20,6 +20,8 @@ diesel_derives = {version = "1.4.1", features = ["sqlite"]}
 futures-core = { version = "0.3", default-features = false }
 pin-project = "1.0.0"
 flowy-net = { path = "../flowy-net" }
+strum = "0.21"
+strum_macros = "0.21"
 
 lazy_static = "1.4.0"
 serde = { version = "1.0", features = ["derive"] }

+ 3 - 3
rust-lib/flowy-workspace/src/entities/app/app_create.rs

@@ -55,16 +55,16 @@ impl TryInto<CreateAppParams> for CreateAppRequest {
 
     fn try_into(self) -> Result<CreateAppParams, Self::Error> {
         let name = AppName::parse(self.name)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::AppNameInvalid).msg(e).build())?;
+            .map_err(|e| ErrorBuilder::new(ErrorCode::AppNameInvalid).msg(e).build())?;
 
         let id = WorkspaceId::parse(self.workspace_id).map_err(|e| {
-            ErrorBuilder::new(WsErrCode::WorkspaceIdInvalid)
+            ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid)
                 .msg(e)
                 .build()
         })?;
 
         let color_style = AppColorStyle::parse(self.color_style).map_err(|e| {
-            ErrorBuilder::new(WsErrCode::AppColorStyleInvalid)
+            ErrorBuilder::new(ErrorCode::AppColorStyleInvalid)
                 .msg(e)
                 .build()
         })?;

+ 2 - 2
rust-lib/flowy-workspace/src/entities/app/app_delete.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::app::parser::AppId,
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
 };
 use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
@@ -22,7 +22,7 @@ impl TryInto<DeleteAppParams> for DeleteAppRequest {
 
     fn try_into(self) -> Result<DeleteAppParams, Self::Error> {
         let app_id = AppId::parse(self.app_id)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::AppIdInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::AppIdInvalid).msg(e).build())?
             .0;
 
         Ok(DeleteAppParams { app_id })

+ 1 - 1
rust-lib/flowy-workspace/src/entities/app/app_query.rs

@@ -70,7 +70,7 @@ impl TryInto<QueryAppParams> for QueryAppRequest {
 
     fn try_into(self) -> Result<QueryAppParams, Self::Error> {
         let app_id = AppId::parse(self.app_id)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::AppIdInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::AppIdInvalid).msg(e).build())?
             .0;
 
         Ok(QueryAppParams {

+ 4 - 4
rust-lib/flowy-workspace/src/entities/app/app_update.rs

@@ -3,7 +3,7 @@ use crate::{
         parser::{AppColorStyle, AppId, AppName},
         ColorStyle,
     },
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
 };
 use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
@@ -73,7 +73,7 @@ impl TryInto<UpdateAppParams> for UpdateAppRequest {
 
     fn try_into(self) -> Result<UpdateAppParams, Self::Error> {
         let app_id = AppId::parse(self.app_id)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::AppIdInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::AppIdInvalid).msg(e).build())?
             .0;
 
         let name = match self.name {
@@ -81,7 +81,7 @@ impl TryInto<UpdateAppParams> for UpdateAppRequest {
             Some(name) => Some(
                 AppName::parse(name)
                     .map_err(|e| {
-                        ErrorBuilder::new(WsErrCode::WorkspaceNameInvalid)
+                        ErrorBuilder::new(ErrorCode::WorkspaceNameInvalid)
                             .msg(e)
                             .build()
                     })?
@@ -94,7 +94,7 @@ impl TryInto<UpdateAppParams> for UpdateAppRequest {
             Some(color_style) => Some(
                 AppColorStyle::parse(color_style)
                     .map_err(|e| {
-                        ErrorBuilder::new(WsErrCode::AppColorStyleInvalid)
+                        ErrorBuilder::new(ErrorCode::AppColorStyleInvalid)
                             .msg(e)
                             .build()
                     })?

+ 4 - 4
rust-lib/flowy-workspace/src/entities/view/view_create.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::{app::parser::AppId, view::parser::*},
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
     impl_def_and_def_mut,
 };
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
@@ -70,11 +70,11 @@ impl TryInto<CreateViewParams> for CreateViewRequest {
 
     fn try_into(self) -> Result<CreateViewParams, Self::Error> {
         let name = ViewName::parse(self.name)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::ViewNameInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::ViewNameInvalid).msg(e).build())?
             .0;
 
         let belong_to_id = AppId::parse(self.belong_to_id)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::AppIdInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::AppIdInvalid).msg(e).build())?
             .0;
 
         let thumbnail = match self.thumbnail {
@@ -82,7 +82,7 @@ impl TryInto<CreateViewParams> for CreateViewRequest {
             Some(thumbnail) => {
                 ViewThumbnail::parse(thumbnail)
                     .map_err(|e| {
-                        ErrorBuilder::new(WsErrCode::ViewThumbnailInvalid)
+                        ErrorBuilder::new(ErrorCode::ViewThumbnailInvalid)
                             .msg(e)
                             .build()
                     })?

+ 2 - 2
rust-lib/flowy-workspace/src/entities/view/view_delete.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::view::parser::ViewId,
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
 };
 use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
@@ -22,7 +22,7 @@ impl TryInto<DeleteViewParams> for DeleteViewRequest {
 
     fn try_into(self) -> Result<DeleteViewParams, Self::Error> {
         let view_id = ViewId::parse(self.view_id)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::ViewIdInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::ViewIdInvalid).msg(e).build())?
             .0;
 
         Ok(DeleteViewParams { view_id })

+ 2 - 2
rust-lib/flowy-workspace/src/entities/view/view_query.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::view::parser::ViewId,
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
 };
 use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
@@ -68,7 +68,7 @@ impl TryInto<QueryViewParams> for QueryViewRequest {
 
     fn try_into(self) -> Result<QueryViewParams, Self::Error> {
         let view_id = ViewId::parse(self.view_id)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::ViewIdInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::ViewIdInvalid).msg(e).build())?
             .0;
 
         Ok(QueryViewParams {

+ 5 - 5
rust-lib/flowy-workspace/src/entities/view/view_update.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::view::parser::{ViewId, *},
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
 };
 use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
@@ -69,14 +69,14 @@ impl TryInto<UpdateViewParams> for UpdateViewRequest {
 
     fn try_into(self) -> Result<UpdateViewParams, Self::Error> {
         let view_id = ViewId::parse(self.view_id)
-            .map_err(|e| ErrorBuilder::new(WsErrCode::ViewIdInvalid).msg(e).build())?
+            .map_err(|e| ErrorBuilder::new(ErrorCode::ViewIdInvalid).msg(e).build())?
             .0;
 
         let name = match self.name {
             None => None,
             Some(name) => Some(
                 ViewName::parse(name)
-                    .map_err(|e| ErrorBuilder::new(WsErrCode::ViewNameInvalid).msg(e).build())?
+                    .map_err(|e| ErrorBuilder::new(ErrorCode::ViewNameInvalid).msg(e).build())?
                     .0,
             ),
         };
@@ -85,7 +85,7 @@ impl TryInto<UpdateViewParams> for UpdateViewRequest {
             None => None,
             Some(desc) => Some(
                 ViewDesc::parse(desc)
-                    .map_err(|e| ErrorBuilder::new(WsErrCode::ViewDescInvalid).msg(e).build())?
+                    .map_err(|e| ErrorBuilder::new(ErrorCode::ViewDescInvalid).msg(e).build())?
                     .0,
             ),
         };
@@ -95,7 +95,7 @@ impl TryInto<UpdateViewParams> for UpdateViewRequest {
             Some(thumbnail) => Some(
                 ViewThumbnail::parse(thumbnail)
                     .map_err(|e| {
-                        ErrorBuilder::new(WsErrCode::ViewThumbnailInvalid)
+                        ErrorBuilder::new(ErrorCode::ViewThumbnailInvalid)
                             .msg(e)
                             .build()
                     })?

+ 3 - 3
rust-lib/flowy-workspace/src/entities/workspace/workspace_create.rs

@@ -35,19 +35,19 @@ impl TryInto<CreateWorkspaceParams> for CreateWorkspaceRequest {
 
     fn try_into(self) -> Result<CreateWorkspaceParams, Self::Error> {
         let name = WorkspaceName::parse(self.name).map_err(|e| {
-            ErrorBuilder::new(WsErrCode::WorkspaceNameInvalid)
+            ErrorBuilder::new(ErrorCode::WorkspaceNameInvalid)
                 .msg(e)
                 .build()
         })?;
 
         let desc = WorkspaceDesc::parse(self.desc).map_err(|e| {
-            ErrorBuilder::new(WsErrCode::WorkspaceDescInvalid)
+            ErrorBuilder::new(ErrorCode::WorkspaceDescInvalid)
                 .msg(e)
                 .build()
         })?;
 
         if self.user_id.is_empty() {
-            return Err(ErrorBuilder::new(WsErrCode::UserIdIsEmpty)
+            return Err(ErrorBuilder::new(ErrorCode::UserIdIsEmpty)
                 .msg("Create workspace failed. UserId is empty")
                 .build());
         }

+ 2 - 2
rust-lib/flowy-workspace/src/entities/workspace/workspace_delete.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::workspace::parser::WorkspaceId,
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
 };
 use flowy_derive::ProtoBuf;
 use std::convert::TryInto;
@@ -23,7 +23,7 @@ impl TryInto<DeleteWorkspaceParams> for DeleteWorkspaceRequest {
     fn try_into(self) -> Result<DeleteWorkspaceParams, Self::Error> {
         let workspace_id = WorkspaceId::parse(self.workspace_id)
             .map_err(|e| {
-                ErrorBuilder::new(WsErrCode::WorkspaceIdInvalid)
+                ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid)
                     .msg(e)
                     .build()
             })?

+ 15 - 1
rust-lib/flowy-workspace/src/entities/workspace/workspace_query.rs

@@ -12,6 +12,20 @@ pub struct QueryWorkspaceRequest {
     pub user_id: String,
 }
 
+impl QueryWorkspaceRequest {
+    pub fn new(user_id: &str) -> Self {
+        Self {
+            workspace_id: None,
+            user_id: user_id.to_owned(),
+        }
+    }
+
+    pub fn workspace_id(mut self, workspace_id: &str) -> Self {
+        self.workspace_id = Some(workspace_id.to_owned());
+        self
+    }
+}
+
 // Read all workspaces if the workspace_id is None
 #[derive(ProtoBuf, Default)]
 pub struct QueryWorkspaceParams {
@@ -46,7 +60,7 @@ impl TryInto<QueryWorkspaceParams> for QueryWorkspaceRequest {
             Some(workspace_id) => Some(
                 WorkspaceId::parse(workspace_id)
                     .map_err(|e| {
-                        ErrorBuilder::new(WsErrCode::WorkspaceIdInvalid)
+                        ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid)
                             .msg(e)
                             .build()
                     })?

+ 2 - 2
rust-lib/flowy-workspace/src/entities/workspace/workspace_update.rs

@@ -37,7 +37,7 @@ impl TryInto<UpdateWorkspaceParams> for UpdateWorkspaceRequest {
             Some(name) => Some(
                 WorkspaceName::parse(name)
                     .map_err(|e| {
-                        ErrorBuilder::new(WsErrCode::WorkspaceNameInvalid)
+                        ErrorBuilder::new(ErrorCode::WorkspaceNameInvalid)
                             .msg(e)
                             .build()
                     })?
@@ -46,7 +46,7 @@ impl TryInto<UpdateWorkspaceParams> for UpdateWorkspaceRequest {
         };
 
         let id = WorkspaceId::parse(self.id).map_err(|e| {
-            ErrorBuilder::new(WsErrCode::WorkspaceIdInvalid)
+            ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid)
                 .msg(e)
                 .build()
         })?;

+ 12 - 12
rust-lib/flowy-workspace/src/errors.rs

@@ -2,20 +2,20 @@ use bytes::Bytes;
 use derive_more::Display;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
 use flowy_dispatch::prelude::{EventResponse, ResponseBuilder};
-use flowy_net::errors::ErrorCode;
+use flowy_net::errors::ErrorCode as NetworkErrorCode;
 use std::convert::TryInto;
 
 #[derive(Debug, Default, Clone, ProtoBuf)]
 pub struct WorkspaceError {
     #[pb(index = 1)]
-    pub code: WsErrCode,
+    pub code: ErrorCode,
 
     #[pb(index = 2)]
     pub msg: String,
 }
 
 impl WorkspaceError {
-    pub fn new(code: WsErrCode, msg: &str) -> Self {
+    pub fn new(code: ErrorCode, msg: &str) -> Self {
         Self {
             code,
             msg: msg.to_owned(),
@@ -24,7 +24,7 @@ impl WorkspaceError {
 }
 
 #[derive(Debug, Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
-pub enum WsErrCode {
+pub enum ErrorCode {
     #[display(fmt = "Unknown")]
     Unknown              = 0,
 
@@ -82,18 +82,18 @@ pub enum WsErrCode {
     RecordNotFound       = 1001,
 }
 
-impl std::default::Default for WsErrCode {
-    fn default() -> Self { WsErrCode::Unknown }
+impl std::default::Default for ErrorCode {
+    fn default() -> Self { ErrorCode::Unknown }
 }
 
 impl std::convert::From<flowy_net::errors::ServerError> for WorkspaceError {
     fn from(error: flowy_net::errors::ServerError) -> Self {
         match error.code {
-            ErrorCode::RecordNotFound => ErrorBuilder::new(WsErrCode::RecordNotFound)
+            NetworkErrorCode::RecordNotFound => ErrorBuilder::new(ErrorCode::RecordNotFound)
                 .error(error.msg)
                 .build(),
 
-            _ => ErrorBuilder::new(WsErrCode::ServerError)
+            _ => ErrorBuilder::new(ErrorCode::ServerError)
                 .error(error.msg)
                 .build(),
         }
@@ -102,7 +102,7 @@ impl std::convert::From<flowy_net::errors::ServerError> for WorkspaceError {
 
 impl std::convert::From<flowy_database::result::Error> for WorkspaceError {
     fn from(error: flowy_database::result::Error) -> Self {
-        ErrorBuilder::new(WsErrCode::WorkspaceDatabaseError)
+        ErrorBuilder::new(ErrorCode::WorkspaceDatabaseError)
             .error(error)
             .build()
     }
@@ -115,8 +115,8 @@ impl flowy_dispatch::Error for WorkspaceError {
     }
 }
 
-pub type ErrorBuilder = flowy_infra::errors::Builder<WsErrCode, WorkspaceError>;
+pub type ErrorBuilder = flowy_infra::errors::Builder<ErrorCode, WorkspaceError>;
 
-impl flowy_infra::errors::Build<WsErrCode> for WorkspaceError {
-    fn build(code: WsErrCode, msg: String) -> Self { WorkspaceError::new(code, &msg) }
+impl flowy_infra::errors::Build<ErrorCode> for WorkspaceError {
+    fn build(code: ErrorCode, msg: String) -> Self { WorkspaceError::new(code, &msg) }
 }

+ 1 - 14
rust-lib/flowy-workspace/src/event.rs

@@ -1,58 +1,45 @@
-use derive_more::Display;
 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 = "WorkspaceError"]
 pub enum WorkspaceEvent {
-    #[display(fmt = "CreateWorkspace")]
     #[event(input = "CreateWorkspaceRequest", output = "Workspace")]
     CreateWorkspace  = 0,
 
-    #[display(fmt = "ReadCurWorkspace")]
     #[event(output = "Workspace")]
     ReadCurWorkspace = 1,
 
-    #[display(fmt = "ReadWorkspaces")]
     #[event(input = "QueryWorkspaceRequest", output = "RepeatedWorkspace")]
     ReadWorkspaces   = 2,
 
-    #[display(fmt = "DeleteWorkspace")]
     #[event(input = "DeleteWorkspaceRequest")]
     DeleteWorkspace  = 3,
 
-    #[display(fmt = "OpenWorkspace")]
     #[event(input = "QueryWorkspaceRequest", output = "Workspace")]
     OpenWorkspace    = 4,
 
-    #[display(fmt = "CreateApp")]
     #[event(input = "CreateAppRequest", output = "App")]
     CreateApp        = 101,
 
-    #[display(fmt = "DeleteApp")]
     #[event(input = "DeleteAppRequest")]
     DeleteApp        = 102,
 
-    #[display(fmt = "ReadApp")]
     #[event(input = "QueryAppRequest", output = "App")]
     ReadApp          = 103,
 
-    #[display(fmt = "UpdateApp")]
     #[event(input = "UpdateAppRequest")]
     UpdateApp        = 104,
 
-    #[display(fmt = "CreateView")]
     #[event(input = "CreateViewRequest", output = "View")]
     CreateView       = 201,
 
-    #[display(fmt = "ReadView")]
     #[event(input = "QueryViewRequest", output = "View")]
     ReadView         = 202,
 
-    #[display(fmt = "UpdateView")]
     #[event(input = "UpdateViewRequest")]
     UpdateView       = 203,
 
-    #[display(fmt = "DeleteView")]
     #[event(input = "DeleteViewRequest")]
     DeleteView       = 204,
 }

+ 2 - 2
rust-lib/flowy-workspace/src/handlers/workspace_handler.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::workspace::*,
-    errors::{ErrorBuilder, WorkspaceError, WsErrCode},
+    errors::{ErrorBuilder, ErrorCode, WorkspaceError},
     services::WorkspaceController,
 };
 use flowy_dispatch::prelude::{data_result, Data, DataResult, Unit};
@@ -42,7 +42,7 @@ pub async fn open_workspace(
 ) -> DataResult<Workspace, WorkspaceError> {
     let params: QueryWorkspaceParams = data.into_inner().try_into()?;
     match params.workspace_id {
-        None => Err(ErrorBuilder::new(WsErrCode::WorkspaceIdInvalid).build()),
+        None => Err(ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid).build()),
         Some(workspace_id) => {
             let workspaces = controller.open_workspace(&workspace_id).await?;
             data_result(workspaces)

+ 58 - 58
rust-lib/flowy-workspace/src/protobuf/model/errors.rs

@@ -26,7 +26,7 @@
 #[derive(PartialEq,Clone,Default)]
 pub struct WorkspaceError {
     // message fields
-    pub code: WsErrCode,
+    pub code: ErrorCode,
     pub msg: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
@@ -44,18 +44,18 @@ impl WorkspaceError {
         ::std::default::Default::default()
     }
 
-    // .WsErrCode code = 1;
+    // .ErrorCode code = 1;
 
 
-    pub fn get_code(&self) -> WsErrCode {
+    pub fn get_code(&self) -> ErrorCode {
         self.code
     }
     pub fn clear_code(&mut self) {
-        self.code = WsErrCode::Unknown;
+        self.code = ErrorCode::Unknown;
     }
 
     // Param is passed by value, moved
-    pub fn set_code(&mut self, v: WsErrCode) {
+    pub fn set_code(&mut self, v: ErrorCode) {
         self.code = v;
     }
 
@@ -113,7 +113,7 @@ impl ::protobuf::Message for WorkspaceError {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if self.code != WsErrCode::Unknown {
+        if self.code != ErrorCode::Unknown {
             my_size += ::protobuf::rt::enum_size(1, self.code);
         }
         if !self.msg.is_empty() {
@@ -125,7 +125,7 @@ impl ::protobuf::Message for WorkspaceError {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if self.code != WsErrCode::Unknown {
+        if self.code != ErrorCode::Unknown {
             os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.code))?;
         }
         if !self.msg.is_empty() {
@@ -169,7 +169,7 @@ impl ::protobuf::Message for WorkspaceError {
         static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
         descriptor.get(|| {
             let mut fields = ::std::vec::Vec::new();
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<WsErrCode>>(
+            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<ErrorCode>>(
                 "code",
                 |m: &WorkspaceError| { &m.code },
                 |m: &mut WorkspaceError| { &mut m.code },
@@ -195,7 +195,7 @@ impl ::protobuf::Message for WorkspaceError {
 
 impl ::protobuf::Clear for WorkspaceError {
     fn clear(&mut self) {
-        self.code = WsErrCode::Unknown;
+        self.code = ErrorCode::Unknown;
         self.msg.clear();
         self.unknown_fields.clear();
     }
@@ -214,7 +214,7 @@ impl ::protobuf::reflect::ProtobufValue for WorkspaceError {
 }
 
 #[derive(Clone,PartialEq,Eq,Debug,Hash)]
-pub enum WsErrCode {
+pub enum ErrorCode {
     Unknown = 0,
     WorkspaceNameInvalid = 1,
     WorkspaceIdInvalid = 2,
@@ -236,57 +236,57 @@ pub enum WsErrCode {
     RecordNotFound = 1001,
 }
 
-impl ::protobuf::ProtobufEnum for WsErrCode {
+impl ::protobuf::ProtobufEnum for ErrorCode {
     fn value(&self) -> i32 {
         *self as i32
     }
 
-    fn from_i32(value: i32) -> ::std::option::Option<WsErrCode> {
+    fn from_i32(value: i32) -> ::std::option::Option<ErrorCode> {
         match value {
-            0 => ::std::option::Option::Some(WsErrCode::Unknown),
-            1 => ::std::option::Option::Some(WsErrCode::WorkspaceNameInvalid),
-            2 => ::std::option::Option::Some(WsErrCode::WorkspaceIdInvalid),
-            3 => ::std::option::Option::Some(WsErrCode::AppColorStyleInvalid),
-            4 => ::std::option::Option::Some(WsErrCode::WorkspaceDescInvalid),
-            5 => ::std::option::Option::Some(WsErrCode::CurrentWorkspaceNotFound),
-            10 => ::std::option::Option::Some(WsErrCode::AppIdInvalid),
-            11 => ::std::option::Option::Some(WsErrCode::AppNameInvalid),
-            20 => ::std::option::Option::Some(WsErrCode::ViewNameInvalid),
-            21 => ::std::option::Option::Some(WsErrCode::ViewThumbnailInvalid),
-            22 => ::std::option::Option::Some(WsErrCode::ViewIdInvalid),
-            23 => ::std::option::Option::Some(WsErrCode::ViewDescInvalid),
-            100 => ::std::option::Option::Some(WsErrCode::DatabaseConnectionFail),
-            101 => ::std::option::Option::Some(WsErrCode::WorkspaceDatabaseError),
-            102 => ::std::option::Option::Some(WsErrCode::UserInternalError),
-            103 => ::std::option::Option::Some(WsErrCode::UserNotLoginYet),
-            104 => ::std::option::Option::Some(WsErrCode::UserIdIsEmpty),
-            1000 => ::std::option::Option::Some(WsErrCode::ServerError),
-            1001 => ::std::option::Option::Some(WsErrCode::RecordNotFound),
+            0 => ::std::option::Option::Some(ErrorCode::Unknown),
+            1 => ::std::option::Option::Some(ErrorCode::WorkspaceNameInvalid),
+            2 => ::std::option::Option::Some(ErrorCode::WorkspaceIdInvalid),
+            3 => ::std::option::Option::Some(ErrorCode::AppColorStyleInvalid),
+            4 => ::std::option::Option::Some(ErrorCode::WorkspaceDescInvalid),
+            5 => ::std::option::Option::Some(ErrorCode::CurrentWorkspaceNotFound),
+            10 => ::std::option::Option::Some(ErrorCode::AppIdInvalid),
+            11 => ::std::option::Option::Some(ErrorCode::AppNameInvalid),
+            20 => ::std::option::Option::Some(ErrorCode::ViewNameInvalid),
+            21 => ::std::option::Option::Some(ErrorCode::ViewThumbnailInvalid),
+            22 => ::std::option::Option::Some(ErrorCode::ViewIdInvalid),
+            23 => ::std::option::Option::Some(ErrorCode::ViewDescInvalid),
+            100 => ::std::option::Option::Some(ErrorCode::DatabaseConnectionFail),
+            101 => ::std::option::Option::Some(ErrorCode::WorkspaceDatabaseError),
+            102 => ::std::option::Option::Some(ErrorCode::UserInternalError),
+            103 => ::std::option::Option::Some(ErrorCode::UserNotLoginYet),
+            104 => ::std::option::Option::Some(ErrorCode::UserIdIsEmpty),
+            1000 => ::std::option::Option::Some(ErrorCode::ServerError),
+            1001 => ::std::option::Option::Some(ErrorCode::RecordNotFound),
             _ => ::std::option::Option::None
         }
     }
 
     fn values() -> &'static [Self] {
-        static values: &'static [WsErrCode] = &[
-            WsErrCode::Unknown,
-            WsErrCode::WorkspaceNameInvalid,
-            WsErrCode::WorkspaceIdInvalid,
-            WsErrCode::AppColorStyleInvalid,
-            WsErrCode::WorkspaceDescInvalid,
-            WsErrCode::CurrentWorkspaceNotFound,
-            WsErrCode::AppIdInvalid,
-            WsErrCode::AppNameInvalid,
-            WsErrCode::ViewNameInvalid,
-            WsErrCode::ViewThumbnailInvalid,
-            WsErrCode::ViewIdInvalid,
-            WsErrCode::ViewDescInvalid,
-            WsErrCode::DatabaseConnectionFail,
-            WsErrCode::WorkspaceDatabaseError,
-            WsErrCode::UserInternalError,
-            WsErrCode::UserNotLoginYet,
-            WsErrCode::UserIdIsEmpty,
-            WsErrCode::ServerError,
-            WsErrCode::RecordNotFound,
+        static values: &'static [ErrorCode] = &[
+            ErrorCode::Unknown,
+            ErrorCode::WorkspaceNameInvalid,
+            ErrorCode::WorkspaceIdInvalid,
+            ErrorCode::AppColorStyleInvalid,
+            ErrorCode::WorkspaceDescInvalid,
+            ErrorCode::CurrentWorkspaceNotFound,
+            ErrorCode::AppIdInvalid,
+            ErrorCode::AppNameInvalid,
+            ErrorCode::ViewNameInvalid,
+            ErrorCode::ViewThumbnailInvalid,
+            ErrorCode::ViewIdInvalid,
+            ErrorCode::ViewDescInvalid,
+            ErrorCode::DatabaseConnectionFail,
+            ErrorCode::WorkspaceDatabaseError,
+            ErrorCode::UserInternalError,
+            ErrorCode::UserNotLoginYet,
+            ErrorCode::UserIdIsEmpty,
+            ErrorCode::ServerError,
+            ErrorCode::RecordNotFound,
         ];
         values
     }
@@ -294,21 +294,21 @@ impl ::protobuf::ProtobufEnum for WsErrCode {
     fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
         static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
         descriptor.get(|| {
-            ::protobuf::reflect::EnumDescriptor::new_pb_name::<WsErrCode>("WsErrCode", file_descriptor_proto())
+            ::protobuf::reflect::EnumDescriptor::new_pb_name::<ErrorCode>("ErrorCode", file_descriptor_proto())
         })
     }
 }
 
-impl ::std::marker::Copy for WsErrCode {
+impl ::std::marker::Copy for ErrorCode {
 }
 
-impl ::std::default::Default for WsErrCode {
+impl ::std::default::Default for ErrorCode {
     fn default() -> Self {
-        WsErrCode::Unknown
+        ErrorCode::Unknown
     }
 }
 
-impl ::protobuf::reflect::ProtobufValue for WsErrCode {
+impl ::protobuf::reflect::ProtobufValue for ErrorCode {
     fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
         ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
     }
@@ -316,8 +316,8 @@ impl ::protobuf::reflect::ProtobufValue for WsErrCode {
 
 static file_descriptor_proto_data: &'static [u8] = b"\
     \n\x0cerrors.proto\"B\n\x0eWorkspaceError\x12\x1e\n\x04code\x18\x01\x20\
-    \x01(\x0e2\n.WsErrCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03\
-    msg*\xb7\x03\n\tWsErrCode\x12\x0b\n\x07Unknown\x10\0\x12\x18\n\x14Worksp\
+    \x01(\x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03\
+    msg*\xb7\x03\n\tErrorCode\x12\x0b\n\x07Unknown\x10\0\x12\x18\n\x14Worksp\
     aceNameInvalid\x10\x01\x12\x16\n\x12WorkspaceIdInvalid\x10\x02\x12\x18\n\
     \x14AppColorStyleInvalid\x10\x03\x12\x18\n\x14WorkspaceDescInvalid\x10\
     \x04\x12\x1c\n\x18CurrentWorkspaceNotFound\x10\x05\x12\x10\n\x0cAppIdInv\

+ 2 - 2
rust-lib/flowy-workspace/src/protobuf/proto/errors.proto

@@ -1,10 +1,10 @@
 syntax = "proto3";
 
 message WorkspaceError {
-    WsErrCode code = 1;
+    ErrorCode code = 1;
     string msg = 2;
 }
-enum WsErrCode {
+enum ErrorCode {
     Unknown = 0;
     WorkspaceNameInvalid = 1;
     WorkspaceIdInvalid = 2;

+ 3 - 3
rust-lib/flowy-workspace/src/services/workspace_controller.rs

@@ -68,7 +68,7 @@ impl WorkspaceController {
             .await?;
 
         match result.first() {
-            None => Err(ErrorBuilder::new(WsErrCode::RecordNotFound).build()),
+            None => Err(ErrorBuilder::new(ErrorCode::RecordNotFound).build()),
             Some(workspace_table) => {
                 let workspace: Workspace = workspace_table.clone().into();
                 set_current_workspace(&workspace.id);
@@ -99,7 +99,7 @@ impl WorkspaceController {
         let mut repeated_workspace = self.read_workspaces(Some(workspace_id.clone())).await?;
 
         if repeated_workspace.is_empty() {
-            return Err(ErrorBuilder::new(WsErrCode::RecordNotFound).build());
+            return Err(ErrorBuilder::new(ErrorCode::RecordNotFound).build());
         }
 
         debug_assert_eq!(repeated_workspace.len(), 1);
@@ -153,7 +153,7 @@ fn set_current_workspace(workspace: &str) {
 
 fn get_current_workspace() -> Result<String, WorkspaceError> {
     match KVStore::get_str(CURRENT_WORKSPACE_ID) {
-        None => Err(ErrorBuilder::new(WsErrCode::CurrentWorkspaceNotFound).build()),
+        None => Err(ErrorBuilder::new(ErrorCode::CurrentWorkspaceNotFound).build()),
         Some(workspace_id) => Ok(workspace_id),
     }
 }

+ 7 - 7
rust-lib/flowy-workspace/tests/event/app_test.rs

@@ -6,7 +6,7 @@ use flowy_workspace::entities::{
 };
 
 #[test]
-fn app_create_success() {
+fn app_create() {
     let workspace = create_workspace("Workspace", "").1;
     let app = create_app("App A", "AppFlowy Github Project", &workspace.id);
     dbg!(&app);
@@ -14,7 +14,7 @@ fn app_create_success() {
 
 #[test]
 #[should_panic]
-fn app_delete_success() {
+fn app_delete() {
     let workspace = create_workspace("Workspace", "").1;
     let app = create_app("App A", "AppFlowy Github Project", &workspace.id);
     delete_app(&app.id);
@@ -23,7 +23,7 @@ fn app_delete_success() {
 }
 
 #[test]
-fn app_create_and_then_get_success() {
+fn app_read() {
     let workspace = create_workspace("Workspace", "").1;
     let app = create_app("App A", "AppFlowy Github Project", &workspace.id);
     let query = QueryAppRequest::new(&app.id);
@@ -32,7 +32,7 @@ fn app_create_and_then_get_success() {
 }
 
 #[test]
-fn app_create_with_view_and_then_get_success() {
+fn app_create_with_view() {
     let workspace = create_workspace("Workspace", "").1;
     let app = create_app("App A", "AppFlowy Github Project", &workspace.id);
     let request_a = CreateViewRequest {
@@ -62,7 +62,7 @@ fn app_create_with_view_and_then_get_success() {
 }
 
 #[test]
-fn app_update_with_trash_flag_and_read_with_trash_flag_success() {
+fn app_set_trash_flag() {
     let app_id = create_app_with_trash_flag();
     let query = QueryAppRequest::new(&app_id).set_is_trash(true);
     let _ = read_app(query);
@@ -70,13 +70,13 @@ fn app_update_with_trash_flag_and_read_with_trash_flag_success() {
 
 #[test]
 #[should_panic]
-fn app_update_with_trash_flag_and_read_without_trash_flag_fail() {
+fn app_set_trash_flag_2() {
     let app_id = create_app_with_trash_flag();
     let query = QueryAppRequest::new(&app_id);
     let _ = read_app(query);
 }
 
-pub fn create_app_with_trash_flag() -> String {
+fn create_app_with_trash_flag() -> String {
     let workspace = create_workspace("Workspace", "").1;
     let app = create_app("App A", "AppFlowy Github Project", &workspace.id);
     let request = UpdateAppRequest {

+ 10 - 10
rust-lib/flowy-workspace/tests/event/helper.rs

@@ -1,4 +1,4 @@
-pub use flowy_test::builder::SingleUserTestBuilder;
+pub use flowy_test::builder::UserTestBuilder;
 use flowy_workspace::{
     entities::{app::*, view::*, workspace::*},
     event::WorkspaceEvent::*,
@@ -12,7 +12,7 @@ pub(crate) fn invalid_workspace_name_test_case() -> Vec<String> {
 }
 
 pub fn create_workspace(name: &str, desc: &str) -> (String, Workspace) {
-    let builder = SingleUserTestBuilder::new();
+    let builder = UserTestBuilder::new();
     let user_id = builder.user_detail.as_ref().unwrap().id.clone();
 
     let request = CreateWorkspaceRequest {
@@ -31,7 +31,7 @@ pub fn create_workspace(name: &str, desc: &str) -> (String, Workspace) {
 }
 
 pub fn read_workspaces(request: QueryWorkspaceRequest) -> Option<Workspace> {
-    let mut repeated_workspace = SingleUserTestBuilder::new()
+    let mut repeated_workspace = UserTestBuilder::new()
         .event(ReadWorkspaces)
         .request(request)
         .sync_send()
@@ -52,7 +52,7 @@ pub fn create_app(name: &str, desc: &str, workspace_id: &str) -> App {
         color_style: Default::default(),
     };
 
-    let app = SingleUserTestBuilder::new()
+    let app = UserTestBuilder::new()
         .event(CreateApp)
         .request(create_app_request)
         .sync_send()
@@ -65,21 +65,21 @@ pub fn delete_app(app_id: &str) {
         app_id: app_id.to_string(),
     };
 
-    SingleUserTestBuilder::new()
+    UserTestBuilder::new()
         .event(DeleteApp)
         .request(delete_app_request)
         .sync_send();
 }
 
 pub fn update_app(request: UpdateAppRequest) {
-    SingleUserTestBuilder::new()
+    UserTestBuilder::new()
         .event(UpdateApp)
         .request(request)
         .sync_send();
 }
 
 pub fn read_app(request: QueryAppRequest) -> App {
-    let app = SingleUserTestBuilder::new()
+    let app = UserTestBuilder::new()
         .event(ReadApp)
         .request(request)
         .sync_send()
@@ -89,7 +89,7 @@ pub fn read_app(request: QueryAppRequest) -> App {
 }
 
 pub fn create_view_with_request(request: CreateViewRequest) -> View {
-    let view = SingleUserTestBuilder::new()
+    let view = UserTestBuilder::new()
         .event(CreateView)
         .request(request)
         .sync_send()
@@ -113,14 +113,14 @@ pub fn create_view() -> View {
 }
 
 pub fn update_view(request: UpdateViewRequest) {
-    SingleUserTestBuilder::new()
+    UserTestBuilder::new()
         .event(UpdateView)
         .request(request)
         .sync_send();
 }
 
 pub fn read_view(request: QueryViewRequest) -> View {
-    SingleUserTestBuilder::new()
+    UserTestBuilder::new()
         .event(ReadView)
         .request(request)
         .sync_send()

+ 4 - 4
rust-lib/flowy-workspace/tests/event/view_test.rs

@@ -3,10 +3,10 @@ use crate::helper::*;
 use flowy_workspace::entities::view::*;
 
 #[test]
-fn view_create_success() { let _ = create_view(); }
+fn view_create() { let _ = create_view(); }
 
 #[test]
-fn view_update_with_trash_flag_and_read_with_trash_flag_success() {
+fn view_set_trash_flag() {
     let view_id = create_view_with_trash_flag();
     let query = QueryViewRequest::new(&view_id).set_is_trash(true);
     let _ = read_view(query);
@@ -14,13 +14,13 @@ fn view_update_with_trash_flag_and_read_with_trash_flag_success() {
 
 #[test]
 #[should_panic]
-fn view_update_with_trash_flag_and_read_without_trash_flag_fail() {
+fn view_set_trash_flag2() {
     let view_id = create_view_with_trash_flag();
     let query = QueryViewRequest::new(&view_id);
     let _ = read_view(query);
 }
 
-pub fn create_view_with_trash_flag() -> String {
+fn create_view_with_trash_flag() -> String {
     let view = create_view();
     let request = UpdateViewRequest {
         view_id: view.id.clone(),

+ 14 - 26
rust-lib/flowy-workspace/tests/event/workspace_test.rs

@@ -14,17 +14,13 @@ use flowy_workspace::{
 fn workspace_create_success() { let _ = create_workspace("First workspace", ""); }
 
 #[test]
-fn workspace_read_all_success() {
+fn workspace_read_all() {
     let (user_id, _) = create_workspace(
         "Workspace A",
         "workspace_create_and_then_get_workspace_success",
     );
-    let request = QueryWorkspaceRequest {
-        workspace_id: None,
-        user_id,
-    };
-
-    let workspaces = SingleUserTestBuilder::new()
+    let request = QueryWorkspaceRequest::new(&user_id);
+    let workspaces = UserTestBuilder::new()
         .event(ReadWorkspaces)
         .request(request)
         .sync_send()
@@ -34,38 +30,30 @@ fn workspace_read_all_success() {
 }
 
 #[test]
-fn workspace_create_and_then_get_workspace_success() {
+fn workspace_create_and_then_get_workspace() {
     let (user_id, workspace) = create_workspace(
         "Workspace A",
         "workspace_create_and_then_get_workspace_success",
     );
-    let request = QueryWorkspaceRequest {
-        workspace_id: Some(workspace.id.clone()),
-        user_id,
-    };
-
+    let request = QueryWorkspaceRequest::new(&user_id).workspace_id(&workspace.id);
     let workspace_from_db = read_workspaces(request).unwrap();
     assert_eq!(workspace.name, workspace_from_db.name);
 }
 
 #[test]
-fn workspace_create_with_apps_success() {
+fn workspace_create_with_apps() {
     let (user_id, workspace) = create_workspace("Workspace", "");
     let app = create_app("App A", "AppFlowy Github Project", &workspace.id);
 
-    let query_workspace_request = QueryWorkspaceRequest {
-        workspace_id: Some(workspace.id),
-        user_id,
-    };
-
-    let workspace_from_db = read_workspaces(query_workspace_request).unwrap();
+    let request = QueryWorkspaceRequest::new(&user_id).workspace_id(&workspace.id);
+    let workspace_from_db = read_workspaces(request).unwrap();
     assert_eq!(&app, workspace_from_db.apps.first_or_crash());
 }
 
 #[test]
-fn workspace_create_with_invalid_name_test() {
+fn workspace_create_with_invalid_name() {
     for name in invalid_workspace_name_test_case() {
-        let builder = SingleUserTestBuilder::new();
+        let builder = UserTestBuilder::new();
         let user_id = builder.user_detail.as_ref().unwrap().id.clone();
 
         let request = CreateWorkspaceRequest {
@@ -81,15 +69,15 @@ fn workspace_create_with_invalid_name_test() {
                 .sync_send()
                 .error()
                 .code,
-            WsErrCode::WorkspaceNameInvalid
+            ErrorCode::WorkspaceNameInvalid
         )
     }
 }
 
 #[test]
-fn workspace_update_with_invalid_name_test() {
+fn workspace_update_with_invalid_name() {
     for name in invalid_workspace_name_test_case() {
-        let builder = SingleUserTestBuilder::new();
+        let builder = UserTestBuilder::new();
         let user_id = builder.user_detail.as_ref().unwrap().id.clone();
 
         let request = CreateWorkspaceRequest {
@@ -105,7 +93,7 @@ fn workspace_update_with_invalid_name_test() {
                 .sync_send()
                 .error()
                 .code,
-            WsErrCode::WorkspaceNameInvalid
+            ErrorCode::WorkspaceNameInvalid
         )
     }
 }