mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-11-09 13:09:21 +03:00
test event from dart to rust using protobuf as bytes adaptor
This commit is contained in:
parent
21b95233fc
commit
2cb26d9e90
@ -13,8 +13,9 @@ class WelcomeScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
getIt<WelcomeBloc>()..add(const WelcomeEvent.check()),
|
||||
create: (context) {
|
||||
return getIt<WelcomeBloc>()..add(const WelcomeEvent.check());
|
||||
},
|
||||
child: Scaffold(
|
||||
body: BlocListener<WelcomeBloc, WelcomeState>(
|
||||
listener: (context, state) {
|
||||
|
@ -55,11 +55,25 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
logger:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -123,6 +123,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -166,6 +173,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
logger:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
33
app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart
Normal file
33
app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart
Normal file
@ -0,0 +1,33 @@
|
||||
/// Auto gen code from rust ast, do not edit
|
||||
part of 'dispatch.dart';
|
||||
|
||||
class UserEventSignIn {
|
||||
UserSignInParams payload;
|
||||
|
||||
UserEventSignIn(this.payload);
|
||||
Future<Either<UserSignInResult, FlowyError>> send() {
|
||||
var request = FFIRequest.create()..event = UserEvent.SignIn.toString();
|
||||
return protobufToBytes(payload).fold(
|
||||
(payload) {
|
||||
request.payload = payload;
|
||||
return Dispatch.asyncRequest(request).then((response) {
|
||||
try {
|
||||
if (response.code != FFIStatusCode.Ok) {
|
||||
return right(FlowyError.from(response));
|
||||
} else {
|
||||
final pb = UserSignInResult.fromBuffer(response.payload);
|
||||
return left(pb);
|
||||
}
|
||||
} catch (e, s) {
|
||||
final error =
|
||||
FlowyError.fromError('${e.runtimeType}. Stack trace: $s');
|
||||
return right(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
(err) => Future(() {
|
||||
return right(FlowyError.fromError(err));
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
88
app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart
Normal file
88
app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart
Normal file
@ -0,0 +1,88 @@
|
||||
import 'dart:ffi';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_logger/flowy_logger.dart';
|
||||
import 'package:flowy_sdk/dispatch/flowy_error.dart';
|
||||
import 'package:flowy_sdk/protobuf/ffi_response.pb.dart';
|
||||
import 'package:isolates/isolates.dart';
|
||||
import 'package:isolates/ports.dart';
|
||||
import 'package:ffi/ffi.dart';
|
||||
// ignore: unused_import
|
||||
import 'package:flutter/services.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/ffi/ffi.dart' as ffi;
|
||||
import 'package:flowy_sdk/protobuf.dart';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
|
||||
part 'code_gen.dart';
|
||||
|
||||
enum FFIException {
|
||||
RequestIsEmpty,
|
||||
}
|
||||
|
||||
class DispatchException implements Exception {
|
||||
FFIException type;
|
||||
DispatchException(this.type);
|
||||
}
|
||||
|
||||
class Dispatch {
|
||||
static Future<FFIResponse> asyncRequest(FFIRequest request) {
|
||||
try {
|
||||
return _asyncRequest(request).future.then((value) {
|
||||
try {
|
||||
final response = FFIResponse.fromBuffer(value);
|
||||
return Future.microtask(() => response);
|
||||
} catch (e, s) {
|
||||
Log.error('FlowyFFI asyncRequest error: ${e.runtimeType}\n');
|
||||
Log.error('Stack trace \n $s');
|
||||
final response = error_response(request, "${e.runtimeType}");
|
||||
return Future.microtask(() => response);
|
||||
}
|
||||
});
|
||||
} catch (e, s) {
|
||||
Log.error('FlowyFFI asyncRequest error: ${e.runtimeType}\n');
|
||||
Log.error('Stack trace \n $s');
|
||||
final response = error_response(request, "${e.runtimeType}");
|
||||
return Future.microtask(() => response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Completer<Uint8List> _asyncRequest(FFIRequest request) {
|
||||
Uint8List bytes = request.writeToBuffer();
|
||||
assert(bytes.isEmpty == false);
|
||||
if (bytes.isEmpty) {
|
||||
throw DispatchException(FFIException.RequestIsEmpty);
|
||||
}
|
||||
|
||||
final Pointer<Uint8> input = calloc.allocate<Uint8>(bytes.length);
|
||||
final list = input.asTypedList(bytes.length);
|
||||
list.setAll(0, bytes);
|
||||
|
||||
final completer = Completer<Uint8List>();
|
||||
final port = singleCompletePort(completer);
|
||||
ffi.async_command(port.nativePort, input, bytes.length);
|
||||
calloc.free(input);
|
||||
|
||||
return completer;
|
||||
}
|
||||
|
||||
FFIResponse error_response(FFIRequest request, String message) {
|
||||
var response = FFIResponse();
|
||||
response.code = FFIStatusCode.Err;
|
||||
response.error = "${request.event}: ${message}";
|
||||
return response;
|
||||
}
|
||||
|
||||
Either<Uint8List, String> protobufToBytes<T extends GeneratedMessage>(
|
||||
T? message) {
|
||||
try {
|
||||
if (message != null) {
|
||||
return left(message.writeToBuffer());
|
||||
} else {
|
||||
return left(Uint8List.fromList([]));
|
||||
}
|
||||
} catch (e, s) {
|
||||
return right('FlowyFFI error: ${e.runtimeType}. Stack trace: $s');
|
||||
}
|
||||
}
|
35
app_flowy/packages/flowy_sdk/lib/dispatch/flowy_error.dart
Normal file
35
app_flowy/packages/flowy_sdk/lib/dispatch/flowy_error.dart
Normal file
@ -0,0 +1,35 @@
|
||||
import '../protobuf/ffi_response.pb.dart';
|
||||
|
||||
class FlowyError {
|
||||
late FFIStatusCode _statusCode;
|
||||
late String _error;
|
||||
|
||||
FFIStatusCode get statusCode {
|
||||
return _statusCode;
|
||||
}
|
||||
|
||||
String get error {
|
||||
return _error;
|
||||
}
|
||||
|
||||
bool get has_error {
|
||||
return _statusCode != FFIStatusCode.Ok;
|
||||
}
|
||||
|
||||
String toString() {
|
||||
return "$_statusCode: $_error";
|
||||
}
|
||||
|
||||
FlowyError({required FFIStatusCode statusCode, required String error}) {
|
||||
_statusCode = statusCode;
|
||||
_error = error;
|
||||
}
|
||||
|
||||
factory FlowyError.from(FFIResponse resp) {
|
||||
return FlowyError(statusCode: resp.code, error: resp.error);
|
||||
}
|
||||
|
||||
factory FlowyError.fromError(String error) {
|
||||
return FlowyError(statusCode: FFIStatusCode.Err, error: error);
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ import 'package:isolates/isolates.dart';
|
||||
// ignore: import_of_legacy_library_into_null_safe
|
||||
import 'package:isolates/ports.dart';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
// ignore: unused_import
|
||||
import 'package:flutter/services.dart';
|
||||
import 'dart:async';
|
||||
|
@ -2,12 +2,16 @@ export 'package:async/async.dart';
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/flowy_error.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'dart:ffi';
|
||||
import 'ffi/adaptor.dart';
|
||||
import 'ffi/ffi.dart' as ffi;
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
import 'package:flowy_sdk/protobuf.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
|
||||
class FlowySDK {
|
||||
static const MethodChannel _channel = MethodChannel('flowy_sdk');
|
||||
static Future<String> get platformVersion async {
|
||||
@ -23,7 +27,20 @@ class FlowySDK {
|
||||
ffi.store_dart_post_cobject(NativeApi.postCObject);
|
||||
|
||||
ffi.init_sdk(sdkDir.path.toNativeUtf8());
|
||||
final resp = await FFIAdaptor.asyncRequest();
|
||||
print(resp);
|
||||
|
||||
final params = UserSignInParams.create();
|
||||
params.email = "nathan.fu@gmail.com";
|
||||
params.password = "Helloworld!2";
|
||||
Either<UserSignInResult, FlowyError> resp =
|
||||
await UserEventSignIn(params).send();
|
||||
|
||||
resp.fold(
|
||||
(result) {
|
||||
print(result);
|
||||
},
|
||||
(error) {
|
||||
print(error);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,5 @@ export 'protobuf/ffi_response.pb.dart';
|
||||
export 'protobuf/ffi_request.pb.dart';
|
||||
export 'protobuf/sign_up.pb.dart';
|
||||
export 'protobuf/sign_in.pb.dart';
|
||||
export 'protobuf/event.pb.dart';
|
||||
export 'protobuf/user.pb.dart';
|
||||
|
11
app_flowy/packages/flowy_sdk/lib/protobuf/event.pb.dart
Normal file
11
app_flowy/packages/flowy_sdk/lib/protobuf/event.pb.dart
Normal file
@ -0,0 +1,11 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: event.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
|
||||
|
||||
import 'dart:core' as $core;
|
||||
|
||||
export 'event.pbenum.dart';
|
||||
|
30
app_flowy/packages/flowy_sdk/lib/protobuf/event.pbenum.dart
Normal file
30
app_flowy/packages/flowy_sdk/lib/protobuf/event.pbenum.dart
Normal file
@ -0,0 +1,30 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: event.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
|
||||
|
||||
// ignore_for_file: UNDEFINED_SHOWN_NAME
|
||||
import 'dart:core' as $core;
|
||||
import 'package:protobuf/protobuf.dart' as $pb;
|
||||
|
||||
class UserEvent extends $pb.ProtobufEnum {
|
||||
static const UserEvent AuthCheck = UserEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AuthCheck');
|
||||
static const UserEvent SignIn = UserEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SignIn');
|
||||
static const UserEvent SignUp = UserEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SignUp');
|
||||
static const UserEvent SignOut = UserEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SignOut');
|
||||
|
||||
static const $core.List<UserEvent> values = <UserEvent> [
|
||||
AuthCheck,
|
||||
SignIn,
|
||||
SignUp,
|
||||
SignOut,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, UserEvent> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
static UserEvent? valueOf($core.int value) => _byValue[value];
|
||||
|
||||
const UserEvent._($core.int v, $core.String n) : super(v, n);
|
||||
}
|
||||
|
18
app_flowy/packages/flowy_sdk/lib/protobuf/event.pbjson.dart
Normal file
18
app_flowy/packages/flowy_sdk/lib/protobuf/event.pbjson.dart
Normal file
@ -0,0 +1,18 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: event.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
|
||||
|
||||
import 'dart:core' as $core;
|
||||
const UserEvent$json = const {
|
||||
'1': 'UserEvent',
|
||||
'2': const [
|
||||
const {'1': 'AuthCheck', '2': 0},
|
||||
const {'1': 'SignIn', '2': 1},
|
||||
const {'1': 'SignUp', '2': 2},
|
||||
const {'1': 'SignOut', '2': 3},
|
||||
],
|
||||
};
|
||||
|
@ -0,0 +1,9 @@
|
||||
///
|
||||
// Generated code. Do not modify.
|
||||
// source: event.proto
|
||||
//
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
|
||||
|
||||
export 'event.pb.dart';
|
||||
|
@ -9,30 +9,34 @@ import 'dart:core' as $core;
|
||||
|
||||
import 'package:protobuf/protobuf.dart' as $pb;
|
||||
|
||||
import 'ffi_response.pbenum.dart';
|
||||
|
||||
export 'ffi_response.pbenum.dart';
|
||||
|
||||
class FFIResponse extends $pb.GeneratedMessage {
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FFIResponse', createEmptyInstance: create)
|
||||
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'event')
|
||||
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'payload', $pb.PbFieldType.OY)
|
||||
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error')
|
||||
..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'payload', $pb.PbFieldType.OY)
|
||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error')
|
||||
..e<FFIStatusCode>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: FFIStatusCode.Unknown, valueOf: FFIStatusCode.valueOf, enumValues: FFIStatusCode.values)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
FFIResponse._() : super();
|
||||
factory FFIResponse({
|
||||
$core.String? event,
|
||||
$core.List<$core.int>? payload,
|
||||
$core.String? error,
|
||||
FFIStatusCode? code,
|
||||
}) {
|
||||
final _result = create();
|
||||
if (event != null) {
|
||||
_result.event = event;
|
||||
}
|
||||
if (payload != null) {
|
||||
_result.payload = payload;
|
||||
}
|
||||
if (error != null) {
|
||||
_result.error = error;
|
||||
}
|
||||
if (code != null) {
|
||||
_result.code = code;
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
factory FFIResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||
@ -57,30 +61,30 @@ class FFIResponse extends $pb.GeneratedMessage {
|
||||
static FFIResponse? _defaultInstance;
|
||||
|
||||
@$pb.TagNumber(1)
|
||||
$core.String get event => $_getSZ(0);
|
||||
$core.List<$core.int> get payload => $_getN(0);
|
||||
@$pb.TagNumber(1)
|
||||
set event($core.String v) { $_setString(0, v); }
|
||||
set payload($core.List<$core.int> v) { $_setBytes(0, v); }
|
||||
@$pb.TagNumber(1)
|
||||
$core.bool hasEvent() => $_has(0);
|
||||
$core.bool hasPayload() => $_has(0);
|
||||
@$pb.TagNumber(1)
|
||||
void clearEvent() => clearField(1);
|
||||
void clearPayload() => clearField(1);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
$core.List<$core.int> get payload => $_getN(1);
|
||||
$core.String get error => $_getSZ(1);
|
||||
@$pb.TagNumber(2)
|
||||
set payload($core.List<$core.int> v) { $_setBytes(1, v); }
|
||||
set error($core.String v) { $_setString(1, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasPayload() => $_has(1);
|
||||
$core.bool hasError() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearPayload() => clearField(2);
|
||||
void clearError() => clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.String get error => $_getSZ(2);
|
||||
FFIStatusCode get code => $_getN(2);
|
||||
@$pb.TagNumber(3)
|
||||
set error($core.String v) { $_setString(2, v); }
|
||||
set code(FFIStatusCode v) { setField(3, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasError() => $_has(2);
|
||||
$core.bool hasCode() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearError() => clearField(3);
|
||||
void clearCode() => clearField(3);
|
||||
}
|
||||
|
||||
|
@ -5,3 +5,24 @@
|
||||
// @dart = 2.12
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
|
||||
|
||||
// ignore_for_file: UNDEFINED_SHOWN_NAME
|
||||
import 'dart:core' as $core;
|
||||
import 'package:protobuf/protobuf.dart' as $pb;
|
||||
|
||||
class FFIStatusCode extends $pb.ProtobufEnum {
|
||||
static const FFIStatusCode Unknown = FFIStatusCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
|
||||
static const FFIStatusCode Ok = FFIStatusCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Ok');
|
||||
static const FFIStatusCode Err = FFIStatusCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Err');
|
||||
|
||||
static const $core.List<FFIStatusCode> values = <FFIStatusCode> [
|
||||
Unknown,
|
||||
Ok,
|
||||
Err,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, FFIStatusCode> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
static FFIStatusCode? valueOf($core.int value) => _byValue[value];
|
||||
|
||||
const FFIStatusCode._($core.int v, $core.String n) : super(v, n);
|
||||
}
|
||||
|
||||
|
@ -6,12 +6,21 @@
|
||||
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
|
||||
|
||||
import 'dart:core' as $core;
|
||||
const FFIResponse$json = const {
|
||||
'1': 'FFIResponse',
|
||||
const FFIStatusCode$json = const {
|
||||
'1': 'FFIStatusCode',
|
||||
'2': const [
|
||||
const {'1': 'event', '3': 1, '4': 1, '5': 9, '10': 'event'},
|
||||
const {'1': 'payload', '3': 2, '4': 1, '5': 12, '10': 'payload'},
|
||||
const {'1': 'error', '3': 3, '4': 1, '5': 9, '10': 'error'},
|
||||
const {'1': 'Unknown', '2': 0},
|
||||
const {'1': 'Ok', '2': 1},
|
||||
const {'1': 'Err', '2': 2},
|
||||
],
|
||||
};
|
||||
|
||||
const FFIResponse$json = const {
|
||||
'1': 'FFIResponse',
|
||||
'2': const [
|
||||
const {'1': 'payload', '3': 1, '4': 1, '5': 12, '10': 'payload'},
|
||||
const {'1': 'error', '3': 2, '4': 1, '5': 9, '10': 'error'},
|
||||
const {'1': 'code', '3': 3, '4': 1, '5': 14, '6': '.FFIStatusCode', '10': 'code'},
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -209,6 +209,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -284,6 +291,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
logger:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -259,7 +259,7 @@ packages:
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
flutter_lints:
|
||||
dependency: "direct main"
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
|
@ -1,10 +1,11 @@
|
||||
mod c;
|
||||
mod model;
|
||||
mod protobuf;
|
||||
mod util;
|
||||
|
||||
use crate::{
|
||||
c::{extend_front_four_bytes_into_bytes, forget_rust},
|
||||
protobuf::FFIRequest,
|
||||
model::{FFIRequest, FFIResponse},
|
||||
};
|
||||
use flowy_sdk::*;
|
||||
use flowy_sys::prelude::*;
|
||||
@ -30,7 +31,7 @@ pub extern "C" fn init_sdk(path: *mut c_char) -> i64 {
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
|
||||
let mut request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
|
||||
let request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
|
||||
log::trace!(
|
||||
"[FFI]: {} Async Event: {:?} with {} port",
|
||||
&request.id,
|
||||
@ -38,16 +39,10 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
|
||||
port
|
||||
);
|
||||
|
||||
request = request.callback(Box::new(move |resp: EventResponse| {
|
||||
let bytes = match resp.payload {
|
||||
Payload::Bytes(bytes) => bytes,
|
||||
Payload::None => vec![],
|
||||
};
|
||||
let _ = EventDispatch::async_send(request, move |resp: EventResponse| {
|
||||
log::trace!("[FFI]: Post data to dart through {} port", port);
|
||||
Box::pin(spawn_future(async { bytes }, port))
|
||||
}));
|
||||
|
||||
let _ = EventDispatch::async_send(request);
|
||||
Box::pin(post_to_flutter(resp, port))
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -66,13 +61,17 @@ pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn link_me_please() {}
|
||||
|
||||
use flowy_sys::prelude::ToBytes;
|
||||
#[inline(always)]
|
||||
async fn spawn_future<F>(future: F, port: i64)
|
||||
where
|
||||
F: Future<Output = Vec<u8>> + Send + 'static,
|
||||
{
|
||||
async fn post_to_flutter(response: EventResponse, port: i64) {
|
||||
let isolate = allo_isolate::Isolate::new(port);
|
||||
match isolate.catch_unwind(future).await {
|
||||
match isolate
|
||||
.catch_unwind(async {
|
||||
let ffi_resp = FFIResponse::from(response);
|
||||
ffi_resp.into_bytes().unwrap()
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(_success) => {
|
||||
log::trace!("[FFI]: Post data to dart success");
|
||||
},
|
||||
@ -85,15 +84,3 @@ where
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<FFIRequest> for DispatchRequest {
|
||||
fn from(ffi_request: FFIRequest) -> Self {
|
||||
let payload = if !ffi_request.payload.is_empty() {
|
||||
Payload::Bytes(ffi_request.payload)
|
||||
} else {
|
||||
Payload::None
|
||||
};
|
||||
let request = DispatchRequest::new(ffi_request.event).payload(payload);
|
||||
request
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_sys::prelude::DispatchRequest;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[derive(Default, ProtoBuf)]
|
||||
pub struct FFIRequest {
|
||||
#[pb(index = 1)]
|
||||
event: String,
|
||||
pub(crate) event: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
payload: Vec<u8>,
|
||||
pub(crate) payload: Vec<u8>,
|
||||
}
|
||||
|
||||
impl FFIRequest {
|
||||
@ -17,3 +18,7 @@ impl FFIRequest {
|
||||
request
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::Into<DispatchRequest> for FFIRequest {
|
||||
fn into(self) -> DispatchRequest { DispatchRequest::new(self.event).payload(self.payload) }
|
||||
}
|
||||
|
@ -1,13 +1,50 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_sys::prelude::{EventResponse, Payload, StatusCode};
|
||||
|
||||
#[derive(ProtoBuf_Enum, Clone, Copy)]
|
||||
pub enum FFIStatusCode {
|
||||
Unknown = 0,
|
||||
Ok = 1,
|
||||
Err = 2,
|
||||
}
|
||||
|
||||
impl std::default::Default for FFIStatusCode {
|
||||
fn default() -> FFIStatusCode { FFIStatusCode::Unknown }
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct FFIResponse {
|
||||
#[pb(index = 1)]
|
||||
event: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
payload: Vec<u8>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
#[pb(index = 2)]
|
||||
error: String,
|
||||
|
||||
#[pb(index = 3)]
|
||||
code: FFIStatusCode,
|
||||
}
|
||||
|
||||
impl std::convert::From<EventResponse> for FFIResponse {
|
||||
fn from(resp: EventResponse) -> Self {
|
||||
let payload = match resp.payload {
|
||||
Payload::Bytes(bytes) => bytes,
|
||||
Payload::None => vec![],
|
||||
};
|
||||
|
||||
let error = match resp.error {
|
||||
Some(e) => format!("{}", e),
|
||||
None => "".to_owned(),
|
||||
};
|
||||
|
||||
let code = match resp.status_code {
|
||||
StatusCode::Ok => FFIStatusCode::Ok,
|
||||
StatusCode::Err => FFIStatusCode::Err,
|
||||
};
|
||||
|
||||
FFIResponse {
|
||||
payload,
|
||||
error,
|
||||
code,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,9 @@
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct FFIResponse {
|
||||
// message fields
|
||||
pub event: ::std::string::String,
|
||||
pub payload: ::std::vec::Vec<u8>,
|
||||
pub error: ::std::string::String,
|
||||
pub code: FFIStatusCode,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
@ -45,33 +45,7 @@ impl FFIResponse {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// string event = 1;
|
||||
|
||||
|
||||
pub fn get_event(&self) -> &str {
|
||||
&self.event
|
||||
}
|
||||
pub fn clear_event(&mut self) {
|
||||
self.event.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_event(&mut self, v: ::std::string::String) {
|
||||
self.event = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_event(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.event
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_event(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.event, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// bytes payload = 2;
|
||||
// bytes payload = 1;
|
||||
|
||||
|
||||
pub fn get_payload(&self) -> &[u8] {
|
||||
@ -97,7 +71,7 @@ impl FFIResponse {
|
||||
::std::mem::replace(&mut self.payload, ::std::vec::Vec::new())
|
||||
}
|
||||
|
||||
// string error = 3;
|
||||
// string error = 2;
|
||||
|
||||
|
||||
pub fn get_error(&self) -> &str {
|
||||
@ -122,6 +96,21 @@ impl FFIResponse {
|
||||
pub fn take_error(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.error, ::std::string::String::new())
|
||||
}
|
||||
|
||||
// .FFIStatusCode code = 3;
|
||||
|
||||
|
||||
pub fn get_code(&self) -> FFIStatusCode {
|
||||
self.code
|
||||
}
|
||||
pub fn clear_code(&mut self) {
|
||||
self.code = FFIStatusCode::Unknown;
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_code(&mut self, v: FFIStatusCode) {
|
||||
self.code = v;
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for FFIResponse {
|
||||
@ -134,14 +123,14 @@ impl ::protobuf::Message for FFIResponse {
|
||||
let (field_number, wire_type) = is.read_tag_unpack()?;
|
||||
match field_number {
|
||||
1 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.event)?;
|
||||
},
|
||||
2 => {
|
||||
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.payload)?;
|
||||
},
|
||||
3 => {
|
||||
2 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.error)?;
|
||||
},
|
||||
3 => {
|
||||
::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.code, 3, &mut self.unknown_fields)?
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
@ -154,14 +143,14 @@ impl ::protobuf::Message for FFIResponse {
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u32 {
|
||||
let mut my_size = 0;
|
||||
if !self.event.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(1, &self.event);
|
||||
}
|
||||
if !self.payload.is_empty() {
|
||||
my_size += ::protobuf::rt::bytes_size(2, &self.payload);
|
||||
my_size += ::protobuf::rt::bytes_size(1, &self.payload);
|
||||
}
|
||||
if !self.error.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(3, &self.error);
|
||||
my_size += ::protobuf::rt::string_size(2, &self.error);
|
||||
}
|
||||
if self.code != FFIStatusCode::Unknown {
|
||||
my_size += ::protobuf::rt::enum_size(3, self.code);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
@ -169,14 +158,14 @@ impl ::protobuf::Message for FFIResponse {
|
||||
}
|
||||
|
||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||
if !self.event.is_empty() {
|
||||
os.write_string(1, &self.event)?;
|
||||
}
|
||||
if !self.payload.is_empty() {
|
||||
os.write_bytes(2, &self.payload)?;
|
||||
os.write_bytes(1, &self.payload)?;
|
||||
}
|
||||
if !self.error.is_empty() {
|
||||
os.write_string(3, &self.error)?;
|
||||
os.write_string(2, &self.error)?;
|
||||
}
|
||||
if self.code != FFIStatusCode::Unknown {
|
||||
os.write_enum(3, ::protobuf::ProtobufEnum::value(&self.code))?;
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
@ -216,11 +205,6 @@ impl ::protobuf::Message for FFIResponse {
|
||||
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::ProtobufTypeString>(
|
||||
"event",
|
||||
|m: &FFIResponse| { &m.event },
|
||||
|m: &mut FFIResponse| { &mut m.event },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
|
||||
"payload",
|
||||
|m: &FFIResponse| { &m.payload },
|
||||
@ -231,6 +215,11 @@ impl ::protobuf::Message for FFIResponse {
|
||||
|m: &FFIResponse| { &m.error },
|
||||
|m: &mut FFIResponse| { &mut m.error },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum<FFIStatusCode>>(
|
||||
"code",
|
||||
|m: &FFIResponse| { &m.code },
|
||||
|m: &mut FFIResponse| { &mut m.code },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<FFIResponse>(
|
||||
"FFIResponse",
|
||||
fields,
|
||||
@ -247,9 +236,9 @@ impl ::protobuf::Message for FFIResponse {
|
||||
|
||||
impl ::protobuf::Clear for FFIResponse {
|
||||
fn clear(&mut self) {
|
||||
self.event.clear();
|
||||
self.payload.clear();
|
||||
self.error.clear();
|
||||
self.code = FFIStatusCode::Unknown;
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
@ -266,20 +255,82 @@ impl ::protobuf::reflect::ProtobufValue for FFIResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
||||
pub enum FFIStatusCode {
|
||||
Unknown = 0,
|
||||
Ok = 1,
|
||||
Err = 2,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for FFIStatusCode {
|
||||
fn value(&self) -> i32 {
|
||||
*self as i32
|
||||
}
|
||||
|
||||
fn from_i32(value: i32) -> ::std::option::Option<FFIStatusCode> {
|
||||
match value {
|
||||
0 => ::std::option::Option::Some(FFIStatusCode::Unknown),
|
||||
1 => ::std::option::Option::Some(FFIStatusCode::Ok),
|
||||
2 => ::std::option::Option::Some(FFIStatusCode::Err),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
|
||||
fn values() -> &'static [Self] {
|
||||
static values: &'static [FFIStatusCode] = &[
|
||||
FFIStatusCode::Unknown,
|
||||
FFIStatusCode::Ok,
|
||||
FFIStatusCode::Err,
|
||||
];
|
||||
values
|
||||
}
|
||||
|
||||
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::<FFIStatusCode>("FFIStatusCode", file_descriptor_proto())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::marker::Copy for FFIStatusCode {
|
||||
}
|
||||
|
||||
impl ::std::default::Default for FFIStatusCode {
|
||||
fn default() -> Self {
|
||||
FFIStatusCode::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for FFIStatusCode {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x12ffi_response.proto\"S\n\x0bFFIResponse\x12\x14\n\x05event\x18\x01\
|
||||
\x20\x01(\tR\x05event\x12\x18\n\x07payload\x18\x02\x20\x01(\x0cR\x07payl\
|
||||
oad\x12\x14\n\x05error\x18\x03\x20\x01(\tR\x05errorJ\xcf\x01\n\x06\x12\
|
||||
\x04\0\0\x06\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\
|
||||
\x02\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x13\n\x0b\n\x04\x04\0\
|
||||
\x02\0\x12\x03\x03\x04\x15\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\
|
||||
\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x10\n\x0c\n\x05\x04\0\x02\0\
|
||||
\x03\x12\x03\x03\x13\x14\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x16\n\
|
||||
\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\t\n\x0c\n\x05\x04\0\x02\x01\
|
||||
\x01\x12\x03\x04\n\x11\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x14\x15\
|
||||
\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\x04\x15\n\x0c\n\x05\x04\0\x02\x02\
|
||||
\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x0b\x10\
|
||||
\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x05\x13\x14b\x06proto3\
|
||||
\n\x12ffi_response.proto\"a\n\x0bFFIResponse\x12\x18\n\x07payload\x18\
|
||||
\x01\x20\x01(\x0cR\x07payload\x12\x14\n\x05error\x18\x02\x20\x01(\tR\x05\
|
||||
error\x12\"\n\x04code\x18\x03\x20\x01(\x0e2\x0e.FFIStatusCodeR\x04code*-\
|
||||
\n\rFFIStatusCode\x12\x0b\n\x07Unknown\x10\0\x12\x06\n\x02Ok\x10\x01\x12\
|
||||
\x07\n\x03Err\x10\x02J\xe2\x02\n\x06\x12\x04\0\0\x0b\x01\n\x08\n\x01\x0c\
|
||||
\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x06\x01\n\n\n\x03\x04\0\
|
||||
\x01\x12\x03\x02\x08\x13\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x16\n\
|
||||
\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\t\n\x0c\n\x05\x04\0\x02\0\x01\
|
||||
\x12\x03\x03\n\x11\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x14\x15\n\x0b\
|
||||
\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x15\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\x10\n\
|
||||
\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x13\x14\n\x0b\n\x04\x04\0\x02\
|
||||
\x02\x12\x03\x05\x04\x1b\n\x0c\n\x05\x04\0\x02\x02\x06\x12\x03\x05\x04\
|
||||
\x11\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x05\x12\x16\n\x0c\n\x05\x04\0\
|
||||
\x02\x02\x03\x12\x03\x05\x19\x1a\n\n\n\x02\x05\0\x12\x04\x07\0\x0b\x01\n\
|
||||
\n\n\x03\x05\0\x01\x12\x03\x07\x05\x12\n\x0b\n\x04\x05\0\x02\0\x12\x03\
|
||||
\x08\x04\x10\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x08\x04\x0b\n\x0c\n\x05\
|
||||
\x05\0\x02\0\x02\x12\x03\x08\x0e\x0f\n\x0b\n\x04\x05\0\x02\x01\x12\x03\t\
|
||||
\x04\x0b\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\t\x04\x06\n\x0c\n\x05\x05\
|
||||
\0\x02\x01\x02\x12\x03\t\t\n\n\x0b\n\x04\x05\0\x02\x02\x12\x03\n\x04\x0c\
|
||||
\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\n\x04\x07\n\x0c\n\x05\x05\0\x02\
|
||||
\x02\x02\x12\x03\n\n\x0bb\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -1,7 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message FFIResponse {
|
||||
string event = 1;
|
||||
bytes payload = 2;
|
||||
string error = 3;
|
||||
bytes payload = 1;
|
||||
string error = 2;
|
||||
FFIStatusCode code = 3;
|
||||
}
|
||||
enum FFIStatusCode {
|
||||
Unknown = 0;
|
||||
Ok = 1;
|
||||
Err = 2;
|
||||
}
|
||||
|
1
rust-lib/dart-ffi/src/util.rs
Normal file
1
rust-lib/dart-ffi/src/util.rs
Normal file
@ -0,0 +1 @@
|
||||
|
@ -25,6 +25,9 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
|
||||
| "UserSignInRequest"
|
||||
| "UserSignInResult"
|
||||
=> TypeCategory::Protobuf,
|
||||
"FFIStatusCode"
|
||||
| "UserEvent"
|
||||
=> TypeCategory::Enum,
|
||||
|
||||
"Option" => TypeCategory::Opt,
|
||||
_ => TypeCategory::Primitive,
|
||||
|
@ -60,7 +60,7 @@ fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option<TokenStream>
|
||||
let ty = ty_info.ty;
|
||||
Some(quote! {
|
||||
if pb.#has_func() {
|
||||
let enum_de_from_pb = #ty::try_from(&mut pb.#get_func()).unwrap();
|
||||
let enum_de_from_pb = #ty::try_from(&pb.#get_func()).unwrap();
|
||||
o.#member = Some(enum_de_from_pb);
|
||||
}
|
||||
})
|
||||
@ -122,7 +122,7 @@ fn token_stream_for_field(
|
||||
TypeCategory::Enum => {
|
||||
let ty = ty_info.ty;
|
||||
Some(quote! {
|
||||
let enum_de_from_pb = #ty::try_from(&mut pb.#member).unwrap();
|
||||
let enum_de_from_pb = #ty::try_from(&pb.#member).unwrap();
|
||||
o.#member = enum_de_from_pb;
|
||||
|
||||
})
|
||||
|
@ -5,27 +5,36 @@ use proc_macro2::TokenStream;
|
||||
pub fn make_enum_token_stream(_ctxt: &Ctxt, cont: &ASTContainer) -> Option<TokenStream> {
|
||||
let enum_ident = &cont.ident;
|
||||
let pb_enum = cont.attrs.pb_enum_type()?;
|
||||
let _build_to_pb_enum = cont.data.all_idents().map(|i| {
|
||||
let build_to_pb_enum = cont.data.all_idents().map(|i| {
|
||||
let token_stream: TokenStream = quote! {
|
||||
#enum_ident::#i => #pb_enum::#i,
|
||||
#enum_ident::#i => crate::protobuf::#pb_enum::#i,
|
||||
};
|
||||
token_stream
|
||||
});
|
||||
|
||||
let build_from_pb_enum = cont.data.all_idents().map(|i| {
|
||||
let token_stream: TokenStream = quote! {
|
||||
#pb_enum::#i => #enum_ident::#i,
|
||||
crate::protobuf::#pb_enum::#i => #enum_ident::#i,
|
||||
};
|
||||
token_stream
|
||||
});
|
||||
|
||||
Some(quote! {
|
||||
impl std::convert::TryFrom<#pb_enum> for #enum_ident {
|
||||
impl std::convert::TryFrom<&crate::protobuf::#pb_enum> for #enum_ident {
|
||||
type Error = String;
|
||||
fn try_from(pb: #pb_enum) -> Result<Self, Self::Error> {
|
||||
match field_type {
|
||||
fn try_from(pb:&crate::protobuf::#pb_enum) -> Result<Self, Self::Error> {
|
||||
Ok(match pb {
|
||||
#(#build_from_pb_enum)*
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryInto<crate::protobuf::#pb_enum> for #enum_ident {
|
||||
type Error = String;
|
||||
fn try_into(self) -> Result<crate::protobuf::#pb_enum, Self::Error> {
|
||||
Ok(match self {
|
||||
#(#build_to_pb_enum)*
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -58,7 +58,7 @@ fn se_token_stream_for_field(ctxt: &Ctxt, field: &ASTField, _take: bool) -> Opti
|
||||
let set_func = format_ident!("set_{}", ident.to_string());
|
||||
Some(quote! {
|
||||
match self.#member {
|
||||
Some(ref s) => { pb.#set_func(s.to_protobuf()) }
|
||||
Some(ref s) => { pb.#set_func(s.try_into().unwrap()) }
|
||||
None => {}
|
||||
}
|
||||
})
|
||||
@ -98,7 +98,7 @@ fn gen_token_stream(
|
||||
}
|
||||
},
|
||||
TypeCategory::Protobuf => Some(
|
||||
quote! { pb.#member = ::protobuf::SingularPtrField::some(self.#member.to_protobuf()); },
|
||||
quote! { pb.#member = ::protobuf::SingularPtrField::some(self.#member.try_into().unwrap()); },
|
||||
),
|
||||
TypeCategory::Opt => {
|
||||
gen_token_stream(ctxt, member, ty_info.bracket_ty_info.unwrap().ty, true)
|
||||
@ -109,7 +109,7 @@ fn gen_token_stream(
|
||||
// flowy_protobuf::#pb_enum_ident::from_i32(self.#member.value()).unwrap();
|
||||
// })
|
||||
Some(quote! {
|
||||
pb.#member = self.#member.to_protobuf();
|
||||
pb.#member = self.#member.try_into().unwrap();
|
||||
})
|
||||
},
|
||||
_ => Some(quote! { pb.#member = self.#member; }),
|
||||
@ -124,7 +124,7 @@ fn token_stream_for_vec(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type) -> Op
|
||||
pb.#member = ::protobuf::RepeatedField::from_vec(
|
||||
self.#member
|
||||
.iter()
|
||||
.map(|m| m.to_protobuf())
|
||||
.map(|m| m.try_into().unwrap())
|
||||
.collect());
|
||||
}),
|
||||
TypeCategory::Bytes => Some(quote! { pb.#member = self.#member.clone(); }),
|
||||
@ -146,7 +146,7 @@ fn token_stream_for_map(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type) -> Op
|
||||
Some(quote! {
|
||||
let mut m: std::collections::HashMap<String, #flowy_protobuf::#value_type> = std::collections::HashMap::new();
|
||||
self.#member.iter().for_each(|(k,v)| {
|
||||
m.insert(k.clone(), v.to_protobuf());
|
||||
m.insert(k.clone(), v.try_into().unwrap());
|
||||
});
|
||||
pb.#member = m;
|
||||
})
|
||||
|
@ -15,8 +15,4 @@ impl FlowySDK {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn async_send(request: DispatchRequest) -> EventResponse {
|
||||
EventDispatch::async_send(request).await
|
||||
}
|
||||
|
||||
pub fn sync_send(request: DispatchRequest) -> EventResponse { EventDispatch::sync_send(request) }
|
||||
|
@ -46,7 +46,14 @@ impl EventDispatch {
|
||||
*(EVENT_DISPATCH.write().unwrap()) = Some(dispatch);
|
||||
}
|
||||
|
||||
pub fn async_send(request: DispatchRequest) -> DispatchFuture {
|
||||
pub fn async_send<Req, Callback>(request: Req, callback: Callback) -> DispatchFuture
|
||||
where
|
||||
Req: std::convert::Into<DispatchRequest>,
|
||||
Callback: FnOnce(EventResponse) -> BoxFuture<'static, ()> + 'static + Send + Sync,
|
||||
{
|
||||
let mut request = request.into();
|
||||
request.callback = Some(Box::new(callback));
|
||||
|
||||
match EVENT_DISPATCH.read() {
|
||||
Ok(dispatch) => {
|
||||
let dispatch = dispatch.as_ref().unwrap();
|
||||
@ -81,7 +88,13 @@ impl EventDispatch {
|
||||
}
|
||||
|
||||
pub fn sync_send(request: DispatchRequest) -> EventResponse {
|
||||
futures::executor::block_on(async { EventDispatch::async_send(request).await })
|
||||
futures::executor::block_on(async {
|
||||
EventDispatch::async_send(request, |response| {
|
||||
dbg!(&response);
|
||||
Box::pin(async {})
|
||||
})
|
||||
.await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,16 +143,9 @@ impl DispatchRequest {
|
||||
|
||||
pub fn payload<P>(mut self, payload: P) -> Self
|
||||
where
|
||||
P: TryInto<Payload, Error = String>,
|
||||
P: Into<Payload>,
|
||||
{
|
||||
let payload = match payload.try_into() {
|
||||
Ok(payload) => payload,
|
||||
Err(e) => {
|
||||
log::error!("{}", e);
|
||||
Payload::None
|
||||
},
|
||||
};
|
||||
self.payload = payload;
|
||||
self.payload = payload.into();
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -10,10 +10,6 @@ pub fn setup_env() {
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn async_send(request: DispatchRequest) -> EventResponse {
|
||||
EventDispatch::async_send(request).await
|
||||
}
|
||||
|
||||
pub fn init_dispatch<F>(module_factory: F)
|
||||
where
|
||||
F: FnOnce() -> Vec<Module>,
|
||||
|
@ -10,6 +10,13 @@ async fn test_init() {
|
||||
init_dispatch(|| vec![Module::new().event(event, hello)]);
|
||||
|
||||
let request = DispatchRequest::new(event);
|
||||
let resp = async_send(request).await;
|
||||
dbg!(&resp);
|
||||
let _ = EventDispatch::async_send(
|
||||
request,
|
||||
Some(|resp| {
|
||||
Box::pin(async move {
|
||||
dbg!(&resp);
|
||||
})
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
@ -66,7 +66,8 @@ impl EventTester {
|
||||
P: ToBytes,
|
||||
{
|
||||
let mut request = self.request.take().unwrap();
|
||||
request = request.payload(Data(payload));
|
||||
let bytes = payload.into_bytes().unwrap();
|
||||
request = request.payload(bytes);
|
||||
self.request = Some(request);
|
||||
self
|
||||
}
|
||||
@ -78,7 +79,9 @@ impl EventTester {
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn async_send(mut self) -> Self {
|
||||
let resp = async_send(self.request.take().unwrap()).await;
|
||||
let resp =
|
||||
EventDispatch::async_send(self.request.take().unwrap(), |_| Box::pin(async {})).await;
|
||||
|
||||
if let Some(ref status_code) = self.assert_status_code {
|
||||
assert_eq!(&resp.status_code, status_code)
|
||||
}
|
||||
|
27
rust-lib/flowy-user/src/domain/event.rs
Normal file
27
rust-lib/flowy-user/src/domain/event.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use derive_more::Display;
|
||||
use flowy_derive::ProtoBuf_Enum;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum)]
|
||||
pub enum UserEvent {
|
||||
#[display(fmt = "AuthCheck")]
|
||||
AuthCheck = 0,
|
||||
#[display(fmt = "SignIn")]
|
||||
SignIn = 1,
|
||||
#[display(fmt = "SignUp")]
|
||||
SignUp = 2,
|
||||
#[display(fmt = "SignOut")]
|
||||
SignOut = 3,
|
||||
}
|
||||
|
||||
// impl std::convert::TryFrom<&crate::protobuf::UserEvent> for UserEvent {
|
||||
// type Error = String;
|
||||
// fn try_from(pb: &crate::protobuf::UserEvent) -> Result<Self, Self::Error>
|
||||
// { let a = UserEvent::SignIn;
|
||||
// match pb {
|
||||
// crate::protobuf::UserEvent::AuthCheck => { UserEvent::SignIn }
|
||||
// UserEvent::SignIn => { UserEvent::SignIn }
|
||||
// UserEvent::SignUp => {UserEvent::SignIn }
|
||||
// UserEvent::SignOut => {UserEvent::SignIn}
|
||||
// }
|
||||
// }
|
||||
// }
|
@ -1,3 +1,4 @@
|
||||
pub mod event;
|
||||
pub mod user;
|
||||
|
||||
pub use user::*;
|
||||
|
@ -5,5 +5,5 @@ pub mod module;
|
||||
mod protobuf;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::{domain::*, handlers::auth::*, module::UserEvent::*};
|
||||
pub use crate::{domain::*, handlers::auth::*};
|
||||
}
|
||||
|
@ -1,20 +1,6 @@
|
||||
use crate::handlers::*;
|
||||
use crate::{domain::event::UserEvent, handlers::*};
|
||||
use flowy_sys::prelude::*;
|
||||
|
||||
use derive_more::Display;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash)]
|
||||
pub enum UserEvent {
|
||||
#[display(fmt = "AuthCheck")]
|
||||
AuthCheck = 0,
|
||||
#[display(fmt = "SignIn")]
|
||||
SignIn = 1,
|
||||
#[display(fmt = "SignUp")]
|
||||
SignUp = 2,
|
||||
#[display(fmt = "SignOut")]
|
||||
SignOut = 3,
|
||||
}
|
||||
|
||||
pub fn create() -> Module {
|
||||
Module::new()
|
||||
.name("Flowy-User")
|
||||
|
108
rust-lib/flowy-user/src/protobuf/model/event.rs
Normal file
108
rust-lib/flowy-user/src/protobuf/model/event.rs
Normal file
@ -0,0 +1,108 @@
|
||||
// This file is generated by rust-protobuf 2.22.1. Do not edit
|
||||
// @generated
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/702
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(clippy::all)]
|
||||
|
||||
#![allow(unused_attributes)]
|
||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
||||
|
||||
#![allow(box_pointers)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(missing_docs)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(trivial_casts)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_results)]
|
||||
//! Generated file from `event.proto`
|
||||
|
||||
/// Generated files are compatible only with the same version
|
||||
/// of protobuf runtime.
|
||||
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
|
||||
|
||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
||||
pub enum UserEvent {
|
||||
AuthCheck = 0,
|
||||
SignIn = 1,
|
||||
SignUp = 2,
|
||||
SignOut = 3,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for UserEvent {
|
||||
fn value(&self) -> i32 {
|
||||
*self as i32
|
||||
}
|
||||
|
||||
fn from_i32(value: i32) -> ::std::option::Option<UserEvent> {
|
||||
match value {
|
||||
0 => ::std::option::Option::Some(UserEvent::AuthCheck),
|
||||
1 => ::std::option::Option::Some(UserEvent::SignIn),
|
||||
2 => ::std::option::Option::Some(UserEvent::SignUp),
|
||||
3 => ::std::option::Option::Some(UserEvent::SignOut),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
|
||||
fn values() -> &'static [Self] {
|
||||
static values: &'static [UserEvent] = &[
|
||||
UserEvent::AuthCheck,
|
||||
UserEvent::SignIn,
|
||||
UserEvent::SignUp,
|
||||
UserEvent::SignOut,
|
||||
];
|
||||
values
|
||||
}
|
||||
|
||||
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::<UserEvent>("UserEvent", file_descriptor_proto())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::marker::Copy for UserEvent {
|
||||
}
|
||||
|
||||
impl ::std::default::Default for UserEvent {
|
||||
fn default() -> Self {
|
||||
UserEvent::AuthCheck
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for UserEvent {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0bevent.proto*?\n\tUserEvent\x12\r\n\tAuthCheck\x10\0\x12\n\n\x06Sig\
|
||||
nIn\x10\x01\x12\n\n\x06SignUp\x10\x02\x12\x0b\n\x07SignOut\x10\x03J\xce\
|
||||
\x01\n\x06\x12\x04\0\0\x07\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
|
||||
\x05\0\x12\x04\x02\0\x07\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x0e\n\
|
||||
\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\x05\x05\0\x02\0\x01\
|
||||
\x12\x03\x03\x04\r\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x10\x11\n\x0b\
|
||||
\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x0f\n\x0c\n\x05\x05\0\x02\x01\x01\
|
||||
\x12\x03\x04\x04\n\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x04\r\x0e\n\x0b\
|
||||
\n\x04\x05\0\x02\x02\x12\x03\x05\x04\x0f\n\x0c\n\x05\x05\0\x02\x02\x01\
|
||||
\x12\x03\x05\x04\n\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\x05\r\x0e\n\x0b\
|
||||
\n\x04\x05\0\x02\x03\x12\x03\x06\x04\x10\n\x0c\n\x05\x05\0\x02\x03\x01\
|
||||
\x12\x03\x06\x04\x0b\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\x06\x0e\x0fb\
|
||||
\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
||||
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
|
||||
::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
|
||||
}
|
||||
|
||||
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
|
||||
file_descriptor_proto_lazy.get(|| {
|
||||
parse_descriptor_proto()
|
||||
})
|
||||
}
|
@ -6,5 +6,8 @@ pub use sign_up::*;
|
||||
mod sign_in;
|
||||
pub use sign_in::*;
|
||||
|
||||
mod event;
|
||||
pub use event::*;
|
||||
|
||||
mod user;
|
||||
pub use user::*;
|
||||
|
8
rust-lib/flowy-user/src/protobuf/proto/event.proto
Normal file
8
rust-lib/flowy-user/src/protobuf/proto/event.proto
Normal file
@ -0,0 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
enum UserEvent {
|
||||
AuthCheck = 0;
|
||||
SignIn = 1;
|
||||
SignUp = 2;
|
||||
SignOut = 3;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use flowy_test::prelude::*;
|
||||
use flowy_user::prelude::*;
|
||||
use flowy_user::prelude::{event::UserEvent::*, *};
|
||||
|
||||
#[test]
|
||||
fn sign_in_with_invalid_email() {
|
||||
|
@ -4,6 +4,11 @@ pub struct EventTemplate {
|
||||
tera_context: Context,
|
||||
}
|
||||
|
||||
pub const DART_IMPORTED: &'static str = r#"
|
||||
/// Auto gen code from rust ast, do not edit
|
||||
part of 'cqrs.dart';
|
||||
"#;
|
||||
|
||||
pub struct EventRenderContext {
|
||||
pub input_deserializer: String,
|
||||
pub output_deserializer: String,
|
||||
@ -21,5 +26,67 @@ impl EventTemplate {
|
||||
|
||||
pub fn render(&mut self, _render_context: EventRenderContext, _index: usize) -> Option<String> {
|
||||
None
|
||||
// if index == 0 {
|
||||
// self.tera_context
|
||||
// .insert("imported_dart_files", DART_IMPORTED)
|
||||
// }
|
||||
// self.tera_context.insert("index", &index);
|
||||
//
|
||||
//
|
||||
//
|
||||
// self.tera_context.insert(
|
||||
// "command_request_struct_ident",
|
||||
// &render_context.command_request_struct_ident,
|
||||
// );
|
||||
//
|
||||
// self.tera_context
|
||||
// .insert("request_deserializer", &render_context.request_deserializer);
|
||||
//
|
||||
// if render_context.request_deserializer.is_empty() {
|
||||
// self.tera_context.insert("has_request_deserializer", &false);
|
||||
// } else {
|
||||
// self.tera_context.insert("has_request_deserializer", &true);
|
||||
// }
|
||||
// self.tera_context
|
||||
// .insert("command_ident", &render_context.event);
|
||||
//
|
||||
// if render_context.response_deserializer.is_empty() {
|
||||
// self.tera_context
|
||||
// .insert("has_response_deserializer", &false);
|
||||
// self.tera_context
|
||||
// .insert("response_deserializer", "ResponsePacket");
|
||||
// } else {
|
||||
// self.tera_context.insert("has_response_deserializer", &true);
|
||||
// self.tera_context.insert(
|
||||
// "response_deserializer",
|
||||
// &render_context.response_deserializer,
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// self.tera_context
|
||||
// .insert("async_cqrs_type", &render_context.async_cqrs_type);
|
||||
// let repo_absolute_path =
|
||||
// std::fs::canonicalize("./flowy-scripts/rust-tool/src/flutter/cqrs")
|
||||
// .unwrap()
|
||||
// .as_path()
|
||||
// .display()
|
||||
// .to_string();
|
||||
//
|
||||
// let template_path = format!("{}/**/*.tera", repo_absolute_path);
|
||||
// let tera = match Tera::new(&template_path) {
|
||||
// Ok(t) => t,
|
||||
// Err(e) => {
|
||||
// log::error!("Parsing error(s): {}", e);
|
||||
// ::std::process::exit(1);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// match tera.render("command_request_template.tera", &self.tera_context) {
|
||||
// Ok(r) => Some(r),
|
||||
// Err(e) => {
|
||||
// log::error!("{:?}", e);
|
||||
// None
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
{%- if index == 0 %}
|
||||
{{ imported_dart_files }}
|
||||
{%- endif -%}
|
||||
|
||||
class {{ command_request_struct_ident }} {
|
||||
{%- if has_request_deserializer %}
|
||||
{{ request_deserializer }} body;
|
||||
{%- else %}
|
||||
Uint8List? body;
|
||||
{%- endif %}
|
||||
|
||||
{%- if has_request_deserializer %}
|
||||
{{ command_request_struct_ident }}(this.body);
|
||||
{%- else %}
|
||||
{{ command_request_struct_ident }}();
|
||||
{%- endif %}
|
||||
Future<Either<{{ response_deserializer }}, FlowyError>> send() {
|
||||
final command = Command.{{ command_ident }};
|
||||
var request = RequestPacket.create()
|
||||
..command = command
|
||||
..id = uuid();
|
||||
|
||||
{%- if has_request_deserializer %}
|
||||
return protobufToBytes(body).fold(
|
||||
(req_bytes) {
|
||||
request.body = req_bytes;
|
||||
return {{ async_cqrs_type }}(request).then((response) {
|
||||
{%- if has_response_deserializer %}
|
||||
try {
|
||||
if (response.hasErr()) {
|
||||
return right(FlowyError.from(response));
|
||||
} else {
|
||||
final pb = {{ response_deserializer }}.fromBuffer(response.body);
|
||||
return left(pb);
|
||||
}
|
||||
|
||||
} catch (e, s) {
|
||||
final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError);
|
||||
return right(error);
|
||||
}
|
||||
{%- else %}
|
||||
return left(response);
|
||||
{%- endif %}
|
||||
});
|
||||
},
|
||||
(err) => Future(() {
|
||||
final error = FlowyError.fromError(err, StatusCode.ProtobufSerializeError);
|
||||
return right(error);
|
||||
}),
|
||||
);
|
||||
{%- else %}
|
||||
return {{ async_cqrs_type }}(request).then((response) {
|
||||
{%- if has_response_deserializer %}
|
||||
try {
|
||||
if (response.hasErr()) {
|
||||
return right(FlowyError.from(response));
|
||||
} else {
|
||||
final pb = {{ response_deserializer }}.fromBuffer(response.body);
|
||||
return left(pb);
|
||||
}
|
||||
} catch (e, s) {
|
||||
final error = FlowyError.fromError('error: ${e.runtimeType}. Stack trace: $s', StatusCode.ProtobufDeserializeError);
|
||||
return right(error);
|
||||
}
|
||||
{%- else %}
|
||||
return left(response);
|
||||
{%- endif %}
|
||||
|
||||
});
|
||||
{%- endif %}
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ pub fn parse_crate_config_from(entry: &walkdir::DirEntry) -> Option<CrateConfig>
|
||||
let folder_name = path.file_stem().unwrap().to_str().unwrap().to_string();
|
||||
let config_path = format!("{}/Flowy.toml", crate_path);
|
||||
|
||||
if std::path::Path::new(&config_path).exists() {
|
||||
if !std::path::Path::new(&config_path).exists() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user