replace response data with payload

This commit is contained in:
appflowy 2021-07-03 22:24:02 +08:00
parent a242b9f036
commit 4a82d7157c
10 changed files with 104 additions and 125 deletions

View file

@ -1,6 +1,6 @@
mod c; mod c;
use crate::c::forget_rust; use crate::c::{extend_front_four_bytes_into_bytes, forget_rust};
use flowy_sdk::*; use flowy_sdk::*;
use flowy_sys::prelude::*; use flowy_sys::prelude::*;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -25,22 +25,18 @@ pub extern "C" fn init_sdk(path: *mut c_char) -> i64 {
#[no_mangle] #[no_mangle]
pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) { pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
let FFICommand { event, payload } = FFICommand::from_u8_pointer(input, len); let mut request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
let mut request = DispatchRequest::new(event);
log::trace!( log::trace!(
"[FFI]: {} Async Event: {:?} with {} port", "[FFI]: {} Async Event: {:?} with {} port",
&request.id, &request.id,
&request.event, &request.event,
port port
); );
if !payload.is_empty() {
request = request.payload(Payload::Bytes(payload));
}
request = request.callback(Box::new(move |resp: EventResponse| { request = request.callback(Box::new(move |resp: EventResponse| {
let bytes = match resp.data { let bytes = match resp.payload {
ResponseData::Bytes(bytes) => bytes, Payload::Bytes(bytes) => bytes,
ResponseData::None => vec![], Payload::None => vec![],
}; };
log::trace!("[FFI]: Post data to dart through {} port", port); log::trace!("[FFI]: Post data to dart through {} port", port);
Box::pin(spawn_future(async { bytes }, port)) Box::pin(spawn_future(async { bytes }, port))
@ -50,26 +46,42 @@ pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 { unimplemented!() } pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 {
let mut request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
log::trace!("[FFI]: {} Sync Event: {:?}", &request.id, &request.event,);
let response = EventDispatch::sync_send(request);
// FFIResponse { }
let response_bytes = vec![];
let result = extend_front_four_bytes_into_bytes(&response_bytes);
forget_rust(result)
}
#[inline(never)] #[inline(never)]
#[no_mangle] #[no_mangle]
pub extern "C" fn link_me_please() {} pub extern "C" fn link_me_please() {}
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]
pub struct FFICommand { pub struct FFIRequest {
event: String, event: String,
payload: Vec<u8>, payload: Vec<u8>,
} }
impl FFICommand { impl FFIRequest {
pub fn from_u8_pointer(pointer: *const u8, len: usize) -> Self { pub fn from_u8_pointer(pointer: *const u8, len: usize) -> Self {
let bytes = unsafe { std::slice::from_raw_parts(pointer, len) }.to_vec(); let bytes = unsafe { std::slice::from_raw_parts(pointer, len) }.to_vec();
let command: FFICommand = serde_json::from_slice(&bytes).unwrap(); let request: FFIRequest = serde_json::from_slice(&bytes).unwrap();
command request
} }
} }
#[derive(serde::Serialize)]
pub struct FFIResponse {
event: String,
payload: Vec<u8>,
error: String,
}
#[inline(always)] #[inline(always)]
async fn spawn_future<F>(future: F, port: i64) async fn spawn_future<F>(future: F, port: i64)
where where
@ -89,3 +101,15 @@ 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 mut request = DispatchRequest::new(ffi_request.event, payload);
request
}
}

View file

@ -33,12 +33,13 @@ pub struct EventTester {
} }
impl EventTester { impl EventTester {
pub fn new<E>(event: E) -> Self pub fn new<E>(event: E, payload: Payload) -> Self
where where
E: Eq + Hash + Debug + Clone + Display, E: Eq + Hash + Debug + Clone + Display,
{ {
init_sdk();
Self { Self {
request: DispatchRequest::new(event), request: DispatchRequest::new(event, payload),
} }
} }
@ -64,7 +65,6 @@ impl EventTester {
#[allow(dead_code)] #[allow(dead_code)]
pub async fn async_send(self) -> EventResponse { pub async fn async_send(self) -> EventResponse {
init_sdk();
let resp = async_send(self.request).await; let resp = async_send(self.request).await;
dbg!(&resp); dbg!(&resp);
resp resp
@ -72,7 +72,6 @@ impl EventTester {
#[allow(dead_code)] #[allow(dead_code)]
pub fn sync_send(self) -> EventResponse { pub fn sync_send(self) -> EventResponse {
init_sdk();
let resp = sync_send(self.request); let resp = sync_send(self.request);
dbg!(&resp); dbg!(&resp);
resp resp

View file

@ -7,7 +7,7 @@ use tokio::time::{sleep, Duration};
#[should_panic] #[should_panic]
fn auth_check_no_payload() { fn auth_check_no_payload() {
let resp = EventTester::new(AuthCheck).sync_send(); let resp = EventTester::new(AuthCheck).sync_send();
assert_eq!(resp.status, StatusCode::Ok); assert_eq!(resp.status_code, StatusCode::Ok);
} }
#[tokio::test] #[tokio::test]

View file

@ -16,12 +16,8 @@ use std::{
future::Future, future::Future,
hash::Hash, hash::Hash,
sync::RwLock, sync::RwLock,
thread::JoinHandle,
};
use tokio::{
macros::support::{Pin, Poll},
task::JoinError,
}; };
use tokio::macros::support::{Pin, Poll};
lazy_static! { lazy_static! {
pub static ref EVENT_DISPATCH: RwLock<Option<EventDispatch>> = RwLock::new(None); pub static ref EVENT_DISPATCH: RwLock<Option<EventDispatch>> = RwLock::new(None);
@ -119,23 +115,18 @@ pub struct DispatchRequest {
} }
impl DispatchRequest { impl DispatchRequest {
pub fn new<E>(event: E) -> Self pub fn new<E>(event: E, payload: Payload) -> Self
where where
E: Eq + Hash + Debug + Clone + Display, E: Eq + Hash + Debug + Clone + Display,
{ {
Self { Self {
payload: Payload::None, payload,
event: event.into(), event: event.into(),
id: uuid::Uuid::new_v4().to_string(), id: uuid::Uuid::new_v4().to_string(),
callback: None, callback: None,
} }
} }
pub fn payload(mut self, payload: Payload) -> Self {
self.payload = payload;
self
}
pub fn callback(mut self, callback: BoxFutureCallback) -> Self { pub fn callback(mut self, callback: BoxFutureCallback) -> Self {
self.callback = Some(callback); self.callback = Some(callback);
self self

View file

@ -1,8 +1,43 @@
use bytes::Bytes;
use std::{fmt, fmt::Formatter};
pub enum PayloadError {} pub enum PayloadError {}
// TODO: support stream data // TODO: support stream data
#[derive(Clone, Debug)] #[derive(Clone, Debug, serde::Serialize)]
pub enum Payload { pub enum Payload {
None, None,
Bytes(Vec<u8>), Bytes(Vec<u8>),
} }
impl std::fmt::Display for Payload {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Payload::Bytes(bytes) => f.write_fmt(format_args!("{} bytes", bytes.len())),
Payload::None => f.write_str("Empty"),
}
}
}
impl std::convert::Into<Payload> for String {
fn into(self) -> Payload { Payload::Bytes(self.into_bytes()) }
}
impl std::convert::Into<Payload> for &'_ String {
fn into(self) -> Payload { Payload::Bytes(self.to_owned().into_bytes()) }
}
impl std::convert::Into<Payload> for Bytes {
fn into(self) -> Payload {
// Opti(nathan): do not copy the bytes?
Payload::Bytes(self.as_ref().to_vec())
}
}
impl std::convert::Into<Payload> for Vec<u8> {
fn into(self) -> Payload { Payload::Bytes(self) }
}
impl std::convert::Into<Payload> for &str {
fn into(self) -> Payload { self.to_string().into() }
}

View file

@ -1,6 +1,7 @@
use crate::{ use crate::{
error::SystemError, error::SystemError,
response::{data::ResponseData, EventResponse, StatusCode}, request::Payload,
response::{EventResponse, StatusCode},
}; };
macro_rules! static_response { macro_rules! static_response {
@ -10,8 +11,8 @@ macro_rules! static_response {
}; };
} }
pub struct ResponseBuilder<T = ResponseData> { pub struct ResponseBuilder<T = Payload> {
pub data: T, pub payload: T,
pub status: StatusCode, pub status: StatusCode,
pub error: Option<SystemError>, pub error: Option<SystemError>,
} }
@ -19,14 +20,14 @@ pub struct ResponseBuilder<T = ResponseData> {
impl ResponseBuilder { impl ResponseBuilder {
pub fn new(status: StatusCode) -> Self { pub fn new(status: StatusCode) -> Self {
ResponseBuilder { ResponseBuilder {
data: ResponseData::None, payload: Payload::None,
status, status,
error: None, error: None,
} }
} }
pub fn data<D: std::convert::Into<ResponseData>>(mut self, data: D) -> Self { pub fn data<D: std::convert::Into<Payload>>(mut self, data: D) -> Self {
self.data = data.into(); self.payload = data.into();
self self
} }
@ -37,8 +38,8 @@ impl ResponseBuilder {
pub fn build(self) -> EventResponse { pub fn build(self) -> EventResponse {
EventResponse { EventResponse {
data: self.data, payload: self.payload,
status: self.status, status_code: self.status,
error: self.error, error: self.error,
} }
} }

View file

@ -1,42 +0,0 @@
use bytes::{Bytes};
use std::{fmt, fmt::Formatter};
#[derive(Debug, Clone)]
// #[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
pub enum ResponseData {
Bytes(Vec<u8>),
None,
}
impl std::fmt::Display for ResponseData {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
ResponseData::Bytes(bytes) => f.write_fmt(format_args!("{} bytes", bytes.len())),
ResponseData::None => f.write_str("Empty"),
}
}
}
impl std::convert::Into<ResponseData> for String {
fn into(self) -> ResponseData { ResponseData::Bytes(self.into_bytes()) }
}
impl std::convert::Into<ResponseData> for &'_ String {
fn into(self) -> ResponseData { ResponseData::Bytes(self.to_owned().into_bytes()) }
}
impl std::convert::Into<ResponseData> for Bytes {
fn into(self) -> ResponseData {
// Opti(nathan): do not copy the bytes?
ResponseData::Bytes(self.as_ref().to_vec())
}
}
impl std::convert::Into<ResponseData> for Vec<u8> {
fn into(self) -> ResponseData { ResponseData::Bytes(self) }
}
impl std::convert::Into<ResponseData> for &str {
fn into(self) -> ResponseData { self.to_string().into() }
}

View file

@ -1,9 +1,7 @@
pub use builder::*; pub use builder::*;
pub use data::*;
pub use responder::*; pub use responder::*;
pub use response::*; pub use response::*;
mod builder; mod builder;
mod data;
mod responder; mod responder;
mod response; mod response;

View file

@ -1,34 +1,29 @@
use crate::{ use crate::{
error::SystemError, error::SystemError,
request::EventRequest, request::{Data, EventRequest, Payload},
response::{data::ResponseData, Responder}, response::Responder,
}; };
use crate::request::Data;
use std::{fmt, fmt::Formatter}; use std::{fmt, fmt::Formatter};
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
// #[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
pub enum StatusCode { pub enum StatusCode {
Ok = 0, Ok = 0,
Err = 1, Err = 1,
} }
// serde user guide: https://serde.rs/field-attrs.html // serde user guide: https://serde.rs/field-attrs.html
#[derive(Debug, Clone)] #[derive(Debug, Clone, serde::Serialize)]
// #[cfg_attr(feature = "use_serde", derive(Serialize))]
pub struct EventResponse { pub struct EventResponse {
pub data: ResponseData, pub payload: Payload,
pub status: StatusCode, pub status_code: StatusCode,
pub error: Option<SystemError>, pub error: Option<SystemError>,
} }
impl EventResponse { impl EventResponse {
pub fn new(status: StatusCode) -> Self { pub fn new(status_code: StatusCode) -> Self {
EventResponse { EventResponse {
data: ResponseData::None, payload: Payload::None,
status, status_code,
error: None, error: None,
} }
} }
@ -36,11 +31,11 @@ impl EventResponse {
impl std::fmt::Display for EventResponse { impl std::fmt::Display for EventResponse {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("Status_Code: {:?}", self.status))?; f.write_fmt(format_args!("Status_Code: {:?}", self.status_code))?;
match &self.data { match &self.payload {
ResponseData::Bytes(b) => f.write_fmt(format_args!("Data: {} bytes", b.len()))?, Payload::Bytes(b) => f.write_fmt(format_args!("Data: {} bytes", b.len()))?,
ResponseData::None => f.write_fmt(format_args!("Data: Empty"))?, Payload::None => f.write_fmt(format_args!("Data: Empty"))?,
} }
match &self.error { match &self.error {
Some(e) => f.write_fmt(format_args!("Error: {:?}", e))?, Some(e) => f.write_fmt(format_args!("Error: {:?}", e))?,
@ -56,28 +51,6 @@ impl Responder for EventResponse {
fn respond_to(self, _: &EventRequest) -> EventResponse { self } fn respond_to(self, _: &EventRequest) -> EventResponse { self }
} }
#[cfg(feature = "use_serde")]
fn serialize_error<S>(error: &Option<SystemError>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match error {
Some(e) => serializer.serialize_str(&format!("{:?}", e)),
None => serializer.serialize_str(""),
}
}
#[cfg(feature = "use_serde")]
fn serialize_data<S>(data: &ResponseData, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match data {
ResponseData::Bytes(bytes) => serializer.serialize_str(&format!("{} bytes", bytes.len())),
ResponseData::None => serializer.serialize_str(""),
}
}
pub fn response_ok<T, E>(data: T) -> Result<Data<T>, E> pub fn response_ok<T, E>(data: T) -> Result<Data<T>, E>
where where
E: Into<SystemError>, E: Into<SystemError>,

View file

@ -9,7 +9,7 @@ async fn test_init() {
let event = "1"; let event = "1";
init_dispatch(|| vec![Module::new().event(event, hello)]); init_dispatch(|| vec![Module::new().event(event, hello)]);
let request = DispatchRequest::new(event); let request = DispatchRequest::new(event, Payload::None);
let resp = async_send(request).await; let resp = async_send(request).await;
dbg!(&resp); dbg!(&resp);
} }