diff --git a/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart b/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart index 6766c71439..1337498e51 100644 --- a/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart +++ b/app_flowy/packages/flowy_sdk/lib/dispatch/code_gen.dart @@ -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> 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> 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)), ); } } diff --git a/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart b/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart index 9bb47e0106..b96b8fdb43 100644 --- a/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -26,29 +26,48 @@ class DispatchException implements Exception { } class Dispatch { - static Future 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> 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 _asyncRequest(FFIRequest request) { +Future> _extractPayload( + Future> responseFuture) { + return responseFuture.then((response) { + return response.fold( + (l) => left(Uint8List.fromList(l.payload)), + (r) => right(r), + ); + }); +} + +Future> _extractResponse( + Completer 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 _sendToRust(FFIRequest request) { Uint8List bytes = request.writeToBuffer(); assert(bytes.isEmpty == false); if (bytes.isEmpty) { @@ -67,14 +86,7 @@ Completer _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 protobufToBytes( +Either paramsToBytes( T? message) { try { if (message != null) { @@ -83,6 +95,32 @@ Either protobufToBytes( 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; +} diff --git a/app_flowy/packages/flowy_sdk/lib/ffi/adaptor.dart b/app_flowy/packages/flowy_sdk/lib/ffi/adaptor.dart deleted file mode 100644 index b5c3b9daa6..0000000000 --- a/app_flowy/packages/flowy_sdk/lib/ffi/adaptor.dart +++ /dev/null @@ -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 toJson() => { - 'event': event, - 'payload': payload, - }; -} - -class FFIAdaptor { - static Completer 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 input = calloc.allocate(bytes.length); - final list = input.asTypedList(bytes.length); - list.setAll(0, bytes); - - final completer = Completer(); - final port = singleCompletePort(completer); - ffi.async_command(port.nativePort, input, bytes.length); - calloc.free(input); - - return completer; - } -} diff --git a/rust-lib/dart-ffi/src/lib.rs b/rust-lib/dart-ffi/src/lib.rs index b03d10308b..18d51dab56 100644 --- a/rust-lib/dart-ffi/src/lib.rs +++ b/rust-lib/dart-ffi/src/lib.rs @@ -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 { } diff --git a/rust-lib/dart-ffi/src/model/ffi_request.rs b/rust-lib/dart-ffi/src/model/ffi_request.rs index 65776be4f2..4fa9900cd8 100644 --- a/rust-lib/dart-ffi/src/model/ffi_request.rs +++ b/rust-lib/dart-ffi/src/model/ffi_request.rs @@ -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 for FFIRequest { - fn into(self) -> DispatchRequest { DispatchRequest::new(self.event).payload(self.payload) } +impl std::convert::Into for FFIRequest { + fn into(self) -> ModuleRequest { ModuleRequest::new(self.event).payload(self.payload) } } diff --git a/rust-lib/flowy-ast/src/attr.rs b/rust-lib/flowy-ast/src/attr.rs index db841b7523..8dc7e393dd 100644 --- a/rust-lib/flowy-ast/src/attr.rs +++ b/rust-lib/flowy-ast/src/attr.rs @@ -353,7 +353,7 @@ impl ASTEnumAttrVariant { } pub fn get_meta_items(cx: &Ctxt, attr: &syn::Attribute) -> Result, ()> { - 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 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(()) }, diff --git a/rust-lib/flowy-derive/src/dart_event/mod.rs b/rust-lib/flowy-derive/src/dart_event/mod.rs new file mode 100644 index 0000000000..df54745b81 --- /dev/null +++ b/rust-lib/flowy-derive/src/dart_event/mod.rs @@ -0,0 +1,4 @@ +use proc_macro2::TokenStream; +pub fn expand_enum_derive(_input: &syn::DeriveInput) -> Result> { + Ok(TokenStream::default()) +} diff --git a/rust-lib/flowy-derive/src/lib.rs b/rust-lib/flowy-derive/src/lib.rs index e12193cd93..3265ae2b10 100644 --- a/rust-lib/flowy-derive/src/lib.rs +++ b/rust-lib/flowy-derive/src/lib.rs @@ -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) -> proc_macro2::TokenStream { let compile_errors = errors.iter().map(syn::Error::to_compile_error); quote!(#(#compile_errors)*) diff --git a/rust-lib/flowy-sdk/src/lib.rs b/rust-lib/flowy-sdk/src/lib.rs index ebde0c64dc..b781d251bd 100644 --- a/rust-lib/flowy-sdk/src/lib.rs +++ b/rust-lib/flowy-sdk/src/lib.rs @@ -14,5 +14,3 @@ impl FlowySDK { EventDispatch::construct(|| build_modules()); } } - -pub fn sync_send(request: DispatchRequest) -> EventResponse { EventDispatch::sync_send(request) } diff --git a/rust-lib/flowy-sys/src/dispatch.rs b/rust-lib/flowy-sys/src/dispatch.rs index 4d1b58c939..f6a07b20ff 100644 --- a/rust-lib/flowy-sys/src/dispatch.rs +++ b/rust-lib/flowy-sys/src/dispatch.rs @@ -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(request: Req, callback: Callback) -> DispatchFuture where - Req: std::convert::Into, + Req: std::convert::Into, 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, } -impl DispatchRequest { - pub fn new(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

(mut self, payload: P) -> Self - where - P: Into, - { - 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) { - 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 for DispatchService { +impl Service for DispatchService { type Response = EventResponse; type Error = SystemError; type Future = BoxFuture<'static, Result>; #[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()) { diff --git a/rust-lib/flowy-sys/src/module/module.rs b/rust-lib/flowy-sys/src/module/module.rs index 57127d32c4..3736c27608 100644 --- a/rust-lib/flowy-sys/src/module/module.rs +++ b/rust-lib/flowy-sys/src/module/module.rs @@ -113,19 +113,27 @@ pub struct ModuleRequest { } impl ModuleRequest { - pub fn new(event: E, id: String, payload: Payload) -> Self + pub fn new(event: E) -> Self where E: Into, { 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

(mut self, payload: P) -> Self + where + P: Into, + { + 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 { diff --git a/rust-lib/flowy-sys/tests/api/module.rs b/rust-lib/flowy-sys/tests/api/module.rs index 17f646ce30..997113e6c2 100644 --- a/rust-lib/flowy-sys/tests/api/module.rs +++ b/rust-lib/flowy-sys/tests/api/module.rs @@ -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; } diff --git a/rust-lib/flowy-test/src/lib.rs b/rust-lib/flowy-test/src/lib.rs index ab00ce1451..7987e1e5a9 100644 --- a/rust-lib/flowy-test/src/lib.rs +++ b/rust-lib/flowy-test/src/lib.rs @@ -42,7 +42,7 @@ fn root_dir() -> String { } pub struct EventTester { - request: Option, + request: Option, assert_status_code: Option, response: Option, } @@ -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 { >::try_from(response.payload).unwrap().into_inner() } } - -fn data_from_response(response: &EventResponse) -> R -where - R: FromBytes, -{ - let result = >::try_from(&response.payload).unwrap().into_inner(); - result -} diff --git a/rust-lib/flowy-user/Flowy.toml b/rust-lib/flowy-user/Flowy.toml index dfa44fb6e4..dc3a6d5933 100644 --- a/rust-lib/flowy-user/Flowy.toml +++ b/rust-lib/flowy-user/Flowy.toml @@ -1,3 +1,3 @@ proto_crates = ["src/domain"] -event_files = ["src/module.rs"] \ No newline at end of file +event_files = ["src/domain/event.rs"] \ No newline at end of file diff --git a/rust-lib/flowy-user/src/domain/event.rs b/rust-lib/flowy-user/src/domain/event.rs index b0f2470a80..ee6f232219 100644 --- a/rust-lib/flowy-user/src/domain/event.rs +++ b/rust-lib/flowy-user/src/domain/event.rs @@ -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 -// { let a = UserEvent::SignIn; -// match pb { -// crate::protobuf::UserEvent::AuthCheck => { UserEvent::SignIn } -// UserEvent::SignIn => { UserEvent::SignIn } -// UserEvent::SignUp => {UserEvent::SignIn } -// UserEvent::SignOut => {UserEvent::SignIn} -// } -// } -// } diff --git a/scripts/flowy-tool/src/dart_event/dart_event.rs b/scripts/flowy-tool/src/dart_event/dart_event.rs index ed00ff8329..536667f161 100644 --- a/scripts/flowy-tool/src/dart_event/dart_event.rs +++ b/scripts/flowy-tool/src/dart_event/dart_event.rs @@ -100,6 +100,7 @@ pub fn parse_event_crate(event_crate: &DartEventCrate) -> Vec { pub fn ast_to_event_render_ctx(ast: &Vec) -> Vec { 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 diff --git a/scripts/flowy-tool/src/dart_event/event_template.rs b/scripts/flowy-tool/src/dart_event/event_template.rs index d1a9e509a5..dfaa830088 100644 --- a/scripts/flowy-tool/src/dart_event/event_template.rs +++ b/scripts/flowy-tool/src/dart_event/event_template.rs @@ -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 { - 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 { + 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 + } + } } } diff --git a/scripts/flowy-tool/src/dart_event/event_template.tera b/scripts/flowy-tool/src/dart_event/event_template.tera index fb0aee7770..43e5570e35 100644 --- a/scripts/flowy-tool/src/dart_event/event_template.tera +++ b/scripts/flowy-tool/src/dart_event/event_template.tera @@ -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> send() { - final command = Command.{{ command_ident }}; - var request = RequestPacket.create() - ..command = command - ..id = uuid(); + Future> 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)), + ); } } + diff --git a/scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs b/scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs index 25e0d6b56d..e49866ea13 100644 --- a/scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs +++ b/scripts/flowy-tool/src/proto/template/derive_meta/derive_meta.rs @@ -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) => { diff --git a/scripts/flowy-tool/src/proto/template/proto_file/enum_template.rs b/scripts/flowy-tool/src/proto/template/proto_file/enum_template.rs index a93337c0b9..ac039b8ca2 100644 --- a/scripts/flowy-tool/src/proto/template/proto_file/enum_template.rs +++ b/scripts/flowy-tool/src/proto/template/proto_file/enum_template.rs @@ -26,7 +26,7 @@ impl EnumTemplate { pub fn render(&mut self) -> Option { 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) => { diff --git a/scripts/flowy-tool/src/proto/template/proto_file/struct_template.rs b/scripts/flowy-tool/src/proto/template/proto_file/struct_template.rs index f45519151c..9037ff0b38 100644 --- a/scripts/flowy-tool/src/proto/template/proto_file/struct_template.rs +++ b/scripts/flowy-tool/src/proto/template/proto_file/struct_template.rs @@ -84,7 +84,7 @@ impl StructTemplate { pub fn render(&mut self) -> Option { 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) => { diff --git a/scripts/flowy-tool/src/util/file.rs b/scripts/flowy-tool/src/util/file.rs index b129e4643c..48befc2990 100644 --- a/scripts/flowy-tool/src/util/file.rs +++ b/scripts/flowy-tool/src/util/file.rs @@ -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) diff --git a/scripts/makefile/protobuf.toml b/scripts/makefile/protobuf.toml index 34f965a425..f9ae926784 100644 --- a/scripts/makefile/protobuf.toml +++ b/scripts/makefile/protobuf.toml @@ -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"