generate the dart side code from the rust side event

This commit is contained in:
appflowy 2021-07-08 13:47:11 +08:00
parent 2cb26d9e90
commit debc8960e0
23 changed files with 255 additions and 364 deletions

View File

@ -1,33 +1,46 @@
/// Auto gen code from rust ast, do not edit
part of 'dispatch.dart';
class UserEventSignIn {
UserSignInParams payload;
class UserEventAuthCheck {
UserSignInParams params;
UserEventAuthCheck(this.params);
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);
}
});
return paramsToBytes(params).fold(
(bytes) {
final request = FFIRequest.create()
..event = UserEvent.AuthCheck.toString()
..payload = bytes;
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(UserSignInResult.fromBuffer(bytes)),
(error) => right(error),
));
},
(err) => Future(() {
return right(FlowyError.fromError(err));
}),
(err) => Future(() => right(err)),
);
}
}
class UserEventSignIn {
UserSignInParams params;
UserEventSignIn(this.params);
Future<Either<UserSignInResult, FlowyError>> send() {
return paramsToBytes(params).fold(
(bytes) {
final request = FFIRequest.create()
..event = UserEvent.SignIn.toString()
..payload = bytes;
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left(UserSignInResult.fromBuffer(bytes)),
(error) => right(error),
));
},
(err) => Future(() => right(err)),
);
}
}

View File

@ -26,29 +26,48 @@ class DispatchException implements Exception {
}
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);
}
static Future<Either<Uint8List, FlowyError>> asyncRequest(
FFIRequest request) {
// FFIRequest => Rust SDK
final bytesFuture = _sendToRust(request);
// Rust SDK => FFIResponse
final responseFuture = _extractResponse(bytesFuture);
// FFIResponse's payload is the bytes of the Response object
final payloadFuture = _extractPayload(responseFuture);
return payloadFuture;
}
}
Completer<Uint8List> _asyncRequest(FFIRequest request) {
Future<Either<Uint8List, FlowyError>> _extractPayload(
Future<Either<FFIResponse, FlowyError>> responseFuture) {
return responseFuture.then((response) {
return response.fold(
(l) => left(Uint8List.fromList(l.payload)),
(r) => right(r),
);
});
}
Future<Either<FFIResponse, FlowyError>> _extractResponse(
Completer<Uint8List> bytesFuture) {
return bytesFuture.future.then((bytes) {
try {
final response = FFIResponse.fromBuffer(bytes);
if (response.code != FFIStatusCode.Ok) {
return right(FlowyError.from(response));
}
return left(response);
} catch (e, s) {
return right(StackTraceError(e, s).toFlowyError());
}
});
}
Completer<Uint8List> _sendToRust(FFIRequest request) {
Uint8List bytes = request.writeToBuffer();
assert(bytes.isEmpty == false);
if (bytes.isEmpty) {
@ -67,14 +86,7 @@ Completer<Uint8List> _asyncRequest(FFIRequest request) {
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>(
Either<Uint8List, FlowyError> paramsToBytes<T extends GeneratedMessage>(
T? message) {
try {
if (message != null) {
@ -83,6 +95,32 @@ Either<Uint8List, String> protobufToBytes<T extends GeneratedMessage>(
return left(Uint8List.fromList([]));
}
} catch (e, s) {
return right('FlowyFFI error: ${e.runtimeType}. Stack trace: $s');
return right(FlowyError.fromError('${e.runtimeType}. Stack trace: $s'));
}
}
class StackTraceError {
Object error;
StackTrace trace;
StackTraceError(
this.error,
this.trace,
);
FlowyError toFlowyError() {
Log.error('${error.runtimeType}\n');
Log.error('Stack trace \n $trace');
return FlowyError.fromError('${error.runtimeType}. Stack trace: $trace');
}
String toString() {
return '${error.runtimeType}. Stack trace: $trace';
}
}
FFIResponse error_response(FFIRequest request, StackTraceError error) {
var response = FFIResponse();
response.code = FFIStatusCode.Err;
response.error = error.toString();
return response;
}

View File

@ -1,61 +0,0 @@
import 'dart:convert';
import 'dart:ffi';
// ignore: import_of_legacy_library_into_null_safe
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';
import 'dart:typed_data';
import 'package:flowy_sdk/ffi/ffi.dart' as ffi;
enum FFIExceptionType {
RequestPacketIsEmpty,
InvalidResponseLength,
ResponsePacketIsInvalid,
}
class FFIAdaptorException implements Exception {
FFIExceptionType type;
FFIAdaptorException(this.type);
}
class FFICommand {
final String event;
final Uint8List payload;
FFICommand(this.event, this.payload);
Map<String, dynamic> toJson() => {
'event': event,
'payload': payload,
};
}
class FFIAdaptor {
static Completer<Uint8List> asyncRequest() {
// final command = FFICommand(
// "AuthCheck", Uint8List.fromList(utf8.encode("this is payload")));
final command = FFICommand("AuthCheck", Uint8List(0));
Uint8List bytes = Uint8List.fromList(utf8.encode(jsonEncode(command)));
assert(bytes.isEmpty == false);
if (bytes.isEmpty) {
throw FFIAdaptorException(FFIExceptionType.RequestPacketIsEmpty);
}
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;
}
}

View File

@ -10,7 +10,7 @@ use crate::{
use flowy_sdk::*;
use flowy_sys::prelude::*;
use lazy_static::lazy_static;
use std::{ffi::CStr, future::Future, os::raw::c_char};
use std::{ffi::CStr, os::raw::c_char};
lazy_static! {
pub static ref FFI_RUNTIME: tokio::runtime::Runtime =
@ -31,11 +31,11 @@ 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 request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into();
log::trace!(
"[FFI]: {} Async Event: {:?} with {} port",
&request.id,
&request.event,
&request.id(),
&request.event(),
port
);
@ -47,8 +47,12 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
#[no_mangle]
pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 {
let request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
log::trace!("[FFI]: {} Sync Event: {:?}", &request.id, &request.event,);
let request: ModuleRequest = FFIRequest::from_u8_pointer(input, len).into();
log::trace!(
"[FFI]: {} Sync Event: {:?}",
&request.id(),
&request.event(),
);
let _response = EventDispatch::sync_send(request);
// FFIResponse { }

View File

@ -1,5 +1,5 @@
use flowy_derive::ProtoBuf;
use flowy_sys::prelude::DispatchRequest;
use flowy_sys::prelude::ModuleRequest;
use std::convert::TryFrom;
#[derive(Default, ProtoBuf)]
@ -19,6 +19,6 @@ impl FFIRequest {
}
}
impl std::convert::Into<DispatchRequest> for FFIRequest {
fn into(self) -> DispatchRequest { DispatchRequest::new(self.event).payload(self.payload) }
impl std::convert::Into<ModuleRequest> for FFIRequest {
fn into(self) -> ModuleRequest { ModuleRequest::new(self.event).payload(self.payload) }
}

View File

@ -353,7 +353,7 @@ impl ASTEnumAttrVariant {
}
pub fn get_meta_items(cx: &Ctxt, attr: &syn::Attribute) -> Result<Vec<syn::NestedMeta>, ()> {
if attr.path != PB_ATTRS {
if attr.path != PB_ATTRS && attr.path != EVENT {
return Ok(Vec::new());
}
@ -361,10 +361,11 @@ pub fn get_meta_items(cx: &Ctxt, attr: &syn::Attribute) -> Result<Vec<syn::Neste
match attr.parse_meta() {
Ok(List(meta)) => Ok(meta.nested.into_iter().collect()),
Ok(other) => {
cx.error_spanned_by(other, "expected #[pb(...)]");
cx.error_spanned_by(other, "expected #[pb(...)] or or #[event(...)]");
Err(())
},
Err(err) => {
cx.error_spanned_by(attr, "attribute must be str, e.g. #[pb(xx = \"xxx\")]");
cx.syn_error(err);
Err(())
},

View File

@ -0,0 +1,4 @@
use proc_macro2::TokenStream;
pub fn expand_enum_derive(_input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
Ok(TokenStream::default())
}

View File

@ -8,6 +8,7 @@ use syn::{parse_macro_input, DeriveInput};
#[macro_use]
extern crate quote;
mod dart_event;
mod derive_cache;
mod proto_buf;
@ -28,6 +29,14 @@ pub fn derive_proto_buf_enum(input: TokenStream) -> TokenStream {
.into()
}
#[proc_macro_derive(Flowy_Event, attributes(event))]
pub fn derive_dart_event(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
dart_event::expand_enum_derive(&input)
.unwrap_or_else(to_compile_errors)
.into()
}
fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
let compile_errors = errors.iter().map(syn::Error::to_compile_error);
quote!(#(#compile_errors)*)

View File

@ -14,5 +14,3 @@ impl FlowySDK {
EventDispatch::construct(|| build_modules());
}
}
pub fn sync_send(request: DispatchRequest) -> EventResponse { EventDispatch::sync_send(request) }

View File

@ -1,7 +1,6 @@
use crate::{
error::{Error, InternalError, SystemError},
module::{as_module_map, Event, Module, ModuleMap, ModuleRequest},
request::Payload,
module::{as_module_map, Module, ModuleMap, ModuleRequest},
response::EventResponse,
service::{Service, ServiceFactory},
util::tokio_default_runtime,
@ -11,13 +10,7 @@ use futures_core::future::BoxFuture;
use futures_util::task::Context;
use lazy_static::lazy_static;
use pin_project::pin_project;
use std::{
convert::TryInto,
fmt::{Debug, Display},
future::Future,
hash::Hash,
sync::RwLock,
};
use std::{future::Future, sync::RwLock};
use tokio::macros::support::{Pin, Poll};
lazy_static! {
@ -48,21 +41,27 @@ impl EventDispatch {
pub fn async_send<Req, Callback>(request: Req, callback: Callback) -> DispatchFuture
where
Req: std::convert::Into<DispatchRequest>,
Req: std::convert::Into<ModuleRequest>,
Callback: FnOnce(EventResponse) -> BoxFuture<'static, ()> + 'static + Send + Sync,
{
let mut request = request.into();
request.callback = Some(Box::new(callback));
let request: ModuleRequest = request.into();
match EVENT_DISPATCH.read() {
Ok(dispatch) => {
let dispatch = dispatch.as_ref().unwrap();
let module_map = dispatch.module_map.clone();
let service = Box::new(DispatchService { module_map });
log::trace!("{}: dispatch {:?} to runtime", &request.id, &request.event);
log::trace!(
"{}: dispatch {:?} to runtime",
&request.id(),
&request.event()
);
let service_ctx = DispatchContext {
request,
callback: Some(Box::new(callback)),
};
let join_handle = dispatch.runtime.spawn(async move {
service
.call(request)
.call(service_ctx)
.await
.unwrap_or_else(|e| InternalError::new(format!("{:?}", e)).as_response())
});
@ -87,7 +86,7 @@ impl EventDispatch {
}
}
pub fn sync_send(request: DispatchRequest) -> EventResponse {
pub fn sync_send(request: ModuleRequest) -> EventResponse {
futures::executor::block_on(async {
EventDispatch::async_send(request, |response| {
dbg!(&response);
@ -120,49 +119,16 @@ pub type BoxFutureCallback =
#[derive(Derivative)]
#[derivative(Debug)]
pub struct DispatchRequest {
pub id: String,
pub event: Event,
pub payload: Payload,
pub struct DispatchContext {
pub request: ModuleRequest,
#[derivative(Debug = "ignore")]
pub callback: Option<BoxFutureCallback>,
}
impl DispatchRequest {
pub fn new<E>(event: E) -> Self
where
E: Eq + Hash + Debug + Clone + Display,
{
Self {
payload: Payload::None,
event: event.into(),
id: uuid::Uuid::new_v4().to_string(),
callback: None,
}
}
pub fn payload<P>(mut self, payload: P) -> Self
where
P: Into<Payload>,
{
self.payload = payload.into();
self
}
pub fn callback(mut self, callback: BoxFutureCallback) -> Self {
self.callback = Some(callback);
self
}
impl DispatchContext {
pub(crate) fn into_parts(self) -> (ModuleRequest, Option<BoxFutureCallback>) {
let DispatchRequest {
event,
payload,
id,
callback,
} = self;
(ModuleRequest::new(event.clone(), id, payload), callback)
let DispatchContext { request, callback } = self;
(request, callback)
}
}
@ -170,22 +136,19 @@ pub(crate) struct DispatchService {
pub(crate) module_map: ModuleMap,
}
impl Service<DispatchRequest> for DispatchService {
impl Service<DispatchContext> for DispatchService {
type Response = EventResponse;
type Error = SystemError;
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
#[cfg_attr(
feature = "use_tracing",
tracing::instrument(
name = "DispatchService",
level = "debug",
skip(self, dispatch_request)
)
tracing::instrument(name = "DispatchService", level = "debug", skip(self, ctx))
)]
fn call(&self, dispatch_request: DispatchRequest) -> Self::Future {
fn call(&self, ctx: DispatchContext) -> Self::Future {
let module_map = self.module_map.clone();
let (request, callback) = dispatch_request.into_parts();
let (request, callback) = ctx.into_parts();
Box::pin(async move {
let result = {
match module_map.get(&request.event()) {

View File

@ -113,19 +113,27 @@ pub struct ModuleRequest {
}
impl ModuleRequest {
pub fn new<E>(event: E, id: String, payload: Payload) -> Self
pub fn new<E>(event: E) -> Self
where
E: Into<Event>,
{
Self {
inner: EventRequest::new(event, id),
payload,
inner: EventRequest::new(event, uuid::Uuid::new_v4().to_string()),
payload: Payload::None,
}
}
pub(crate) fn id(&self) -> &str { &self.inner.id }
pub fn payload<P>(mut self, payload: P) -> Self
where
P: Into<Payload>,
{
self.payload = payload.into();
self
}
pub(crate) fn event(&self) -> &Event { &self.inner.event }
pub fn id(&self) -> &str { &self.inner.id }
pub fn event(&self) -> &Event { &self.inner.event }
}
impl std::fmt::Display for ModuleRequest {

View File

@ -9,14 +9,11 @@ async fn test_init() {
let event = "1";
init_dispatch(|| vec![Module::new().event(event, hello)]);
let request = DispatchRequest::new(event);
let _ = EventDispatch::async_send(
request,
Some(|resp| {
Box::pin(async move {
dbg!(&resp);
})
}),
)
let request = ModuleRequest::new(event);
let _ = EventDispatch::async_send(request, |resp| {
Box::pin(async move {
dbg!(&resp);
})
})
.await;
}

View File

@ -42,7 +42,7 @@ fn root_dir() -> String {
}
pub struct EventTester {
request: Option<DispatchRequest>,
request: Option<ModuleRequest>,
assert_status_code: Option<StatusCode>,
response: Option<EventResponse>,
}
@ -53,7 +53,7 @@ impl EventTester {
E: Eq + Hash + Debug + Clone + Display,
{
init_sdk();
let request = DispatchRequest::new(event);
let request = ModuleRequest::new(event);
Self {
request: Some(request),
assert_status_code: None,
@ -91,7 +91,8 @@ impl EventTester {
}
pub fn sync_send(mut self) -> Self {
let resp = sync_send(self.request.take().unwrap());
let resp = EventDispatch::sync_send(self.request.take().unwrap());
if let Some(ref status_code) = self.assert_status_code {
assert_eq!(&resp.status_code, status_code)
}
@ -108,11 +109,3 @@ impl EventTester {
<Data<R>>::try_from(response.payload).unwrap().into_inner()
}
}
fn data_from_response<R>(response: &EventResponse) -> R
where
R: FromBytes,
{
let result = <Data<R>>::try_from(&response.payload).unwrap().into_inner();
result
}

View File

@ -1,3 +1,3 @@
proto_crates = ["src/domain"]
event_files = ["src/module.rs"]
event_files = ["src/domain/event.rs"]

View File

@ -1,10 +1,12 @@
use derive_more::Display;
use flowy_derive::ProtoBuf_Enum;
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
pub enum UserEvent {
#[display(fmt = "AuthCheck")]
#[event(input = "UserSignInParams", output = "UserSignInResult")]
AuthCheck = 0,
#[event(input = "UserSignInParams", output = "UserSignInResult")]
#[display(fmt = "SignIn")]
SignIn = 1,
#[display(fmt = "SignUp")]
@ -12,16 +14,3 @@ pub enum UserEvent {
#[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}
// }
// }
// }

View File

@ -100,6 +100,7 @@ pub fn parse_event_crate(event_crate: &DartEventCrate) -> Vec<EventASTContext> {
pub fn ast_to_event_render_ctx(ast: &Vec<EventASTContext>) -> Vec<EventRenderContext> {
ast.iter()
.filter(|event_ast| event_ast.event_input.is_some() && event_ast.event_output.is_some())
.map(|event_ast| EventRenderContext {
input_deserializer: event_ast
.event_input

View File

@ -1,3 +1,4 @@
use crate::util::get_tera;
use tera::Context;
pub struct EventTemplate {
@ -6,7 +7,7 @@ pub struct EventTemplate {
pub const DART_IMPORTED: &'static str = r#"
/// Auto gen code from rust ast, do not edit
part of 'cqrs.dart';
part of 'dispatch.dart';
"#;
pub struct EventRenderContext {
@ -24,69 +25,30 @@ 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
// }
// }
pub fn render(&mut self, ctx: EventRenderContext, index: usize) -> Option<String> {
if index == 0 {
self.tera_context
.insert("imported_dart_files", DART_IMPORTED)
}
self.tera_context.insert("index", &index);
let dart_class_name = format!("{}{}", ctx.event_ty, ctx.event);
let event = format!("{}.{}", ctx.event_ty, ctx.event);
self.tera_context.insert("event_class", &dart_class_name);
self.tera_context.insert("event", &event);
self.tera_context
.insert("input_deserializer", &ctx.input_deserializer);
self.tera_context
.insert("output_deserializer", &ctx.output_deserializer);
let tera = get_tera("dart_event");
match tera.render("event_template.tera", &self.tera_context) {
Ok(r) => Some(r),
Err(e) => {
log::error!("{:?}", e);
None
}
}
}
}

View File

@ -2,71 +2,25 @@
{{ imported_dart_files }}
{%- endif -%}
class {{ command_request_struct_ident }} {
{%- if has_request_deserializer %}
{{ request_deserializer }} body;
{%- else %}
Uint8List? body;
{%- endif %}
class {{ event_class }} {
{{ input_deserializer }} params;
{{ event_class }}(this.params);
{%- 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();
Future<Either<{{ output_deserializer }}, FlowyError>> send() {
return paramsToBytes(params).fold(
(bytes) {
final request = FFIRequest.create()
..event = {{ event }}.toString()
..payload = bytes;
{%- 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 %}
});
return Dispatch.asyncRequest(request)
.then((bytesResult) => bytesResult.fold(
(bytes) => left({{ output_deserializer }}.fromBuffer(bytes)),
(error) => right(error),
));
},
(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 %}
(err) => Future(() => right(err)),
);
}
}

View File

@ -24,7 +24,7 @@ impl ProtobufDeriveMeta {
self.context.insert("names", &self.structs);
self.context.insert("enums", &self.enums);
let tera = get_tera("derive_meta");
let tera = get_tera("proto/template/derive_meta");
match tera.render("derive_meta.tera", &self.context) {
Ok(r) => Some(r),
Err(e) => {

View File

@ -26,7 +26,7 @@ impl EnumTemplate {
pub fn render(&mut self) -> Option<String> {
self.context.insert("items", &self.items);
let tera = get_tera("proto_file");
let tera = get_tera("proto/template/proto_file");
match tera.render("enum.tera", &self.context) {
Ok(r) => Some(r),
Err(e) => {

View File

@ -84,7 +84,7 @@ impl StructTemplate {
pub fn render(&mut self) -> Option<String> {
self.context.insert("fields", &self.fields);
let tera = get_tera("proto_file");
let tera = get_tera("proto/template/proto_file");
match tera.render("struct.tera", &self.context) {
Ok(r) => Some(r),
Err(e) => {

View File

@ -89,7 +89,7 @@ pub fn print_diff(old_content: String, new_content: String) {
}
pub fn get_tera(directory: &str) -> Tera {
let mut root = "./scripts/flowy-tool/src/proto/template/".to_owned();
let mut root = "./scripts/flowy-tool/src/".to_owned();
root.push_str(directory);
let root_absolute_path = std::fs::canonicalize(root)

View File

@ -5,7 +5,7 @@ dependencies = ["gen_pb_file"]
[tasks.gen_pb_file]
script = [
"""
pb_gen_bin=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/scripts/flowy-tool/Cargo.toml
flowy_tool=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/scripts/flowy-tool/Cargo.toml
rust_source=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/
rust_lib=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib
flutter_lib=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/packages
@ -14,10 +14,28 @@ script = [
flutter_package_lib=${flutter_lib}/flowy_sdk/lib
cargo run \
--manifest-path ${pb_gen_bin} pb-gen \
--manifest-path ${flowy_tool} pb-gen \
--rust_source=${rust_source} \
--derive_meta=${derive_meta} \
--flutter_package_lib=${flutter_package_lib}
""",
]
script_runner = "@shell"
[tasks.gen_dart_event]
script = [
"""
flowy_tool=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/scripts/flowy-tool/Cargo.toml
flutter_lib=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/app_flowy/packages
rust_source=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/rust-lib/
output=${flutter_lib}/flowy_sdk/lib/dispatch/code_gen.dart
cargo run \
--manifest-path ${flowy_tool} dart-event \
--rust_source=${rust_source} \
--output=${output}
""",
]
script_runner = "@shell"