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;
use crate::c::forget_rust;
use crate::c::{extend_front_four_bytes_into_bytes, forget_rust};
use flowy_sdk::*;
use flowy_sys::prelude::*;
use lazy_static::lazy_static;
@ -25,22 +25,18 @@ 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 FFICommand { event, payload } = FFICommand::from_u8_pointer(input, len);
let mut request = DispatchRequest::new(event);
let mut request: DispatchRequest = FFIRequest::from_u8_pointer(input, len).into();
log::trace!(
"[FFI]: {} Async Event: {:?} with {} port",
&request.id,
&request.event,
port
);
if !payload.is_empty() {
request = request.payload(Payload::Bytes(payload));
}
request = request.callback(Box::new(move |resp: EventResponse| {
let bytes = match resp.data {
ResponseData::Bytes(bytes) => bytes,
ResponseData::None => vec![],
let bytes = match resp.payload {
Payload::Bytes(bytes) => bytes,
Payload::None => vec![],
};
log::trace!("[FFI]: Post data to dart through {} port", 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]
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)]
#[no_mangle]
pub extern "C" fn link_me_please() {}
#[derive(serde::Deserialize)]
pub struct FFICommand {
pub struct FFIRequest {
event: String,
payload: Vec<u8>,
}
impl FFICommand {
impl FFIRequest {
pub fn from_u8_pointer(pointer: *const u8, len: usize) -> Self {
let bytes = unsafe { std::slice::from_raw_parts(pointer, len) }.to_vec();
let command: FFICommand = serde_json::from_slice(&bytes).unwrap();
command
let request: FFIRequest = serde_json::from_slice(&bytes).unwrap();
request
}
}
#[derive(serde::Serialize)]
pub struct FFIResponse {
event: String,
payload: Vec<u8>,
error: String,
}
#[inline(always)]
async fn spawn_future<F>(future: F, port: i64)
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 {
pub fn new<E>(event: E) -> Self
pub fn new<E>(event: E, payload: Payload) -> Self
where
E: Eq + Hash + Debug + Clone + Display,
{
init_sdk();
Self {
request: DispatchRequest::new(event),
request: DispatchRequest::new(event, payload),
}
}
@ -64,7 +65,6 @@ impl EventTester {
#[allow(dead_code)]
pub async fn async_send(self) -> EventResponse {
init_sdk();
let resp = async_send(self.request).await;
dbg!(&resp);
resp
@ -72,7 +72,6 @@ impl EventTester {
#[allow(dead_code)]
pub fn sync_send(self) -> EventResponse {
init_sdk();
let resp = sync_send(self.request);
dbg!(&resp);
resp

View File

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

View File

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

View File

@ -1,8 +1,43 @@
use bytes::Bytes;
use std::{fmt, fmt::Formatter};
pub enum PayloadError {}
// TODO: support stream data
#[derive(Clone, Debug)]
#[derive(Clone, Debug, serde::Serialize)]
pub enum Payload {
None,
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::{
error::SystemError,
response::{data::ResponseData, EventResponse, StatusCode},
request::Payload,
response::{EventResponse, StatusCode},
};
macro_rules! static_response {
@ -10,8 +11,8 @@ macro_rules! static_response {
};
}
pub struct ResponseBuilder<T = ResponseData> {
pub data: T,
pub struct ResponseBuilder<T = Payload> {
pub payload: T,
pub status: StatusCode,
pub error: Option<SystemError>,
}
@ -19,14 +20,14 @@ pub struct ResponseBuilder<T = ResponseData> {
impl ResponseBuilder {
pub fn new(status: StatusCode) -> Self {
ResponseBuilder {
data: ResponseData::None,
payload: Payload::None,
status,
error: None,
}
}
pub fn data<D: std::convert::Into<ResponseData>>(mut self, data: D) -> Self {
self.data = data.into();
pub fn data<D: std::convert::Into<Payload>>(mut self, data: D) -> Self {
self.payload = data.into();
self
}
@ -37,8 +38,8 @@ impl ResponseBuilder {
pub fn build(self) -> EventResponse {
EventResponse {
data: self.data,
status: self.status,
payload: self.payload,
status_code: self.status,
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 data::*;
pub use responder::*;
pub use response::*;
mod builder;
mod data;
mod responder;
mod response;

View File

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

View File

@ -9,7 +9,7 @@ async fn test_init() {
let event = "1";
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;
dbg!(&resp);
}