diff --git a/.idea/appflowy_client.iml b/.idea/appflowy_client.iml index 94f61ad366..42434a43ef 100644 --- a/.idea/appflowy_client.iml +++ b/.idea/appflowy_client.iml @@ -10,6 +10,7 @@ + diff --git a/rust-lib/Cargo.toml b/rust-lib/Cargo.toml index 3424af727f..b2d90e77fb 100644 --- a/rust-lib/Cargo.toml +++ b/rust-lib/Cargo.toml @@ -4,6 +4,7 @@ members = [ "flowy-sdk", "dart-ffi", "flowy-log", + "flowy-user", ] [profile.dev] diff --git a/rust-lib/flowy-log/src/lib.rs b/rust-lib/flowy-log/src/lib.rs index d402821c00..af26c09d0a 100644 --- a/rust-lib/flowy-log/src/lib.rs +++ b/rust-lib/flowy-log/src/lib.rs @@ -1,10 +1,9 @@ -use log::SetLoggerError; use tracing::subscriber::set_global_default; use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer}; use tracing_log::LogTracer; use tracing_subscriber::{layer::SubscriberExt, EnvFilter}; -pub fn init_log(name: &str, env_filter: &str) -> std::Result<(), SetLoggerError> { +pub fn init_log(name: &str, env_filter: &str) -> std::result::Result<(), String> { let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(env_filter.to_owned())); let formatting_layer = BunyanFormattingLayer::new(name.to_owned(), std::io::stdout); let subscriber = tracing_subscriber::fmt() @@ -17,8 +16,8 @@ pub fn init_log(name: &str, env_filter: &str) -> std::Result<(), SetLoggerError> .with(JsonStorageLayer) .with(formatting_layer); - let _ = LogTracer::init()?; - let _ = set_global_default(subscriber)?; + let _ = LogTracer::init().map_err(|e| format!("{:?}", e))?; + let _ = set_global_default(subscriber).map_err(|e| format!("{:?}", e))?; Ok(()) } @@ -28,7 +27,7 @@ mod tests { #[test] fn test_log() { - init_log("flowy-log", "info"); + init_log("flowy-log", "info").unwrap(); tracing::info!("😁 Tracing info log"); log::info!("😁 bridge 'log' to 'tracing'"); } diff --git a/rust-lib/flowy-sdk/Cargo.toml b/rust-lib/flowy-sdk/Cargo.toml index 197f6ed2d6..a4576af753 100644 --- a/rust-lib/flowy-sdk/Cargo.toml +++ b/rust-lib/flowy-sdk/Cargo.toml @@ -6,4 +6,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -flowy-sys = { path = "../flowy-sys" } \ No newline at end of file +flowy-sys = { path = "../flowy-sys" } +flowy-log = { path = "../flowy-log" } \ No newline at end of file diff --git a/rust-lib/flowy-sys/src/module/module.rs b/rust-lib/flowy-sys/src/module/module.rs index 01bad43ae8..4f2b57fd43 100644 --- a/rust-lib/flowy-sys/src/module/module.rs +++ b/rust-lib/flowy-sys/src/module/module.rs @@ -17,14 +17,22 @@ use futures_core::{future::LocalBoxFuture, ready}; use pin_project::pin_project; use std::{ collections::HashMap, + fmt::{Debug, Display}, future::Future, + hash::Hash, pin::Pin, rc::Rc, task::{Context, Poll}, }; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}; -pub type Event = String; +#[derive(PartialEq, Eq, Hash, Debug, Clone)] +pub struct Event(String); + +impl std::convert::From for Event { + fn from(t: T) -> Self { Event(format!("{}", t)) } +} + pub type EventServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, SystemError>; pub struct Module { @@ -57,15 +65,17 @@ impl Module { self } - pub fn event(mut self, event: Event, handler: H) -> Self + pub fn event(mut self, event: E, handler: H) -> Self where H: Handler, T: FromRequest + 'static, R: Future + 'static, R::Output: Responder + 'static, + E: Eq + Hash + Debug + Clone + Display, { + let event: Event = event.into(); if self.service_map.contains_key(&event) { - log::error!("Duplicate Event: {}", &event); + log::error!("Duplicate Event: {:?}", &event); } Rc::get_mut(&mut self.service_map) diff --git a/rust-lib/flowy-sys/src/request/request.rs b/rust-lib/flowy-sys/src/request/request.rs index 12aafd415a..68b7800c02 100644 --- a/rust-lib/flowy-sys/src/request/request.rs +++ b/rust-lib/flowy-sys/src/request/request.rs @@ -2,22 +2,30 @@ use std::future::Future; use crate::{ error::SystemError, + module::Event, request::payload::Payload, util::ready::{ready, Ready}, }; +use std::{ + fmt::{Debug, Display}, + hash::Hash, +}; #[derive(Clone, Debug)] pub struct EventRequest { id: String, - event: String, + event: Event, data: Option>, } impl EventRequest { - pub fn new(event: String) -> EventRequest { + pub fn new(event: E) -> EventRequest + where + E: Eq + Hash + Debug + Clone + Display, + { Self { id: uuid::Uuid::new_v4().to_string(), - event, + event: event.into(), data: None, } } @@ -27,7 +35,7 @@ impl EventRequest { self } - pub fn get_event(&self) -> &str { &self.event } + pub fn get_event(&self) -> &Event { &self.event } pub fn get_id(&self) -> &str { &self.id } diff --git a/rust-lib/flowy-sys/src/response/data.rs b/rust-lib/flowy-sys/src/response/data.rs index 4be2edd98f..7602701166 100644 --- a/rust-lib/flowy-sys/src/response/data.rs +++ b/rust-lib/flowy-sys/src/response/data.rs @@ -1,3 +1,4 @@ +use bytes::{Buf, Bytes}; use serde::{Deserialize, Serialize}; use std::{fmt, fmt::Formatter}; @@ -20,6 +21,14 @@ impl std::convert::Into for String { fn into(self) -> ResponseData { ResponseData::Bytes(self.into_bytes()) } } +impl std::convert::Into for &'_ String { + fn into(self) -> ResponseData { ResponseData::Bytes(self.to_owned().into_bytes()) } +} + +impl std::convert::Into for Bytes { + fn into(self) -> ResponseData { ResponseData::Bytes(self.bytes().to_vec()) } +} + impl std::convert::Into for &str { fn into(self) -> ResponseData { self.to_string().into() } } diff --git a/rust-lib/flowy-sys/src/response/responder.rs b/rust-lib/flowy-sys/src/response/responder.rs index 98d4a261c6..03348d4e95 100644 --- a/rust-lib/flowy-sys/src/response/responder.rs +++ b/rust-lib/flowy-sys/src/response/responder.rs @@ -1,7 +1,9 @@ use crate::{ + error::SystemError, request::EventRequest, response::{EventResponse, EventResponseBuilder}, }; +use bytes::Bytes; pub trait Responder { fn respond_to(self, req: &EventRequest) -> EventResponse; @@ -17,3 +19,18 @@ macro_rules! impl_responder { impl_responder!(&'static str); impl_responder!(String); +impl_responder!(&'_ String); +impl_responder!(Bytes); + +impl Responder for Result +where + T: Responder, + E: Into, +{ + fn respond_to(self, request: &EventRequest) -> EventResponse { + match self { + Ok(val) => val.respond_to(request), + Err(e) => e.into().into(), + } + } +} diff --git a/rust-lib/flowy-sys/src/stream.rs b/rust-lib/flowy-sys/src/stream.rs index 91c6cc515c..56cbf2ce55 100644 --- a/rust-lib/flowy-sys/src/stream.rs +++ b/rust-lib/flowy-sys/src/stream.rs @@ -6,7 +6,7 @@ use crate::{ system::ModuleMap, }; use futures_core::{future::LocalBoxFuture, ready, task::Context}; -use std::future::Future; +use std::{future::Future, hash::Hash}; use tokio::{ macros::support::{Pin, Poll}, sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, @@ -38,7 +38,10 @@ struct CommandSenderService { module_map: ModuleMap, } -impl Service> for CommandSenderService { +impl Service> for CommandSenderService +where + T: 'static, +{ type Response = EventResponse; type Error = SystemError; type Future = LocalBoxFuture<'static, Result>; @@ -109,7 +112,10 @@ where service_factor_impl!(CommandSender); -impl CommandSender { +impl CommandSender +where + T: 'static, +{ pub fn new(module_map: ModuleMap) -> Self { let (data_tx, data_rx) = unbounded_channel::>(); Self { @@ -135,14 +141,20 @@ impl CommandSender { pub fn take_data_rx(&mut self) -> UnboundedReceiver> { self.data_rx.take().unwrap() } } -pub struct CommandSenderRunner { +pub struct CommandSenderRunner +where + T: 'static, +{ module_map: ModuleMap, data_rx: UnboundedReceiver>, } service_factor_impl!(CommandSenderRunner); -impl CommandSenderRunner { +impl CommandSenderRunner +where + T: 'static, +{ pub fn new(module_map: ModuleMap, data_rx: UnboundedReceiver>) -> Self { Self { module_map, data_rx } } diff --git a/rust-lib/flowy-sys/src/system.rs b/rust-lib/flowy-sys/src/system.rs index 2db8c18fd6..d300aaac84 100644 --- a/rust-lib/flowy-sys/src/system.rs +++ b/rust-lib/flowy-sys/src/system.rs @@ -4,7 +4,7 @@ use crate::{ stream::CommandSenderRunner, }; use futures_core::{ready, task::Context}; -use std::{cell::RefCell, collections::HashMap, future::Future, io, rc::Rc, sync::Arc}; +use std::{cell::RefCell, collections::HashMap, fmt::Debug, future::Future, io, rc::Rc, sync::Arc}; use tokio::{ macros::support::{Pin, Poll}, sync::{ @@ -30,6 +30,7 @@ pub struct FlowySystem { impl FlowySystem { pub fn construct(module_factory: F, sender_factory: S) -> SystemRunner where + // E: Into> + Eq + Hash + Debug + Clone + 'static, F: FnOnce() -> Vec, S: FnOnce(ModuleMap) -> CommandSenderRunner, T: 'static, diff --git a/rust-lib/flowy-sys/tests/api/helper.rs b/rust-lib/flowy-sys/tests/api/helper.rs index d8c43c976d..3b9ea955ce 100644 --- a/rust-lib/flowy-sys/tests/api/helper.rs +++ b/rust-lib/flowy-sys/tests/api/helper.rs @@ -1,9 +1,5 @@ use flowy_sys::prelude::{CommandData, CommandSender, CommandSenderRunner, EventResponse, FlowySystem, Module}; -use std::{ - cell::RefCell, - sync::{Once, RwLock}, - task::Context, -}; +use std::{cell::RefCell, sync::Once}; #[allow(dead_code)] pub fn setup_env() { diff --git a/rust-lib/flowy-sys/tests/api/main.rs b/rust-lib/flowy-sys/tests/api/main.rs index 21ac62726e..6147b588f8 100644 --- a/rust-lib/flowy-sys/tests/api/main.rs +++ b/rust-lib/flowy-sys/tests/api/main.rs @@ -1,2 +1,2 @@ mod helper; -mod module_event; +mod module; diff --git a/rust-lib/flowy-sys/tests/api/module.rs b/rust-lib/flowy-sys/tests/api/module.rs new file mode 100644 index 0000000000..e7095b6809 --- /dev/null +++ b/rust-lib/flowy-sys/tests/api/module.rs @@ -0,0 +1,23 @@ +use crate::helper::*; +use flowy_sys::prelude::*; + +pub async fn hello() -> String { "say hello".to_string() } +#[test] +fn test_init() { + setup_env(); + + let event = "1"; + let modules = vec![Module::new().event(event, hello)]; + + init_system(modules, move || { + let request = EventRequest::new(event); + let stream_data = CommandData::new(1, Some(request)).with_callback(Box::new(|_config, response| { + log::info!("async resp: {:?}", response); + })); + + let resp = sync_send(stream_data); + log::info!("sync resp: {:?}", resp); + + stop_system(); + }); +} diff --git a/rust-lib/flowy-sys/tests/api/module_event.rs b/rust-lib/flowy-sys/tests/api/module_event.rs deleted file mode 100644 index 5cf14a570a..0000000000 --- a/rust-lib/flowy-sys/tests/api/module_event.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::helper::*; -use flowy_sys::prelude::*; - -pub async fn no_params() -> String { "no params function call".to_string() } -pub async fn one_params(_s: String) -> String { "one params function call".to_string() } -pub async fn two_params(_s1: String, _s2: String) -> String { "two params function call".to_string() } - -#[test] -fn test_init() { - setup_env(); - - let no_params_command = "no params".to_string(); - let one_params_command = "one params".to_string(); - let two_params_command = "two params".to_string(); - - let modules = vec![Module::new() - .event(no_params_command.clone(), no_params) - .event(one_params_command.clone(), one_params) - .event(two_params_command.clone(), two_params)]; - - init_system(modules, || { - let request = EventRequest::new(no_params_command); - let stream_data = CommandData::new(1, Some(request)).with_callback(Box::new(|_config, response| { - log::info!("async resp: {:?}", response); - })); - - let resp = sync_send(stream_data); - log::info!("sync resp: {:?}", resp); - - stop_system(); - }); -} diff --git a/rust-lib/flowy-user/Cargo.toml b/rust-lib/flowy-user/Cargo.toml new file mode 100644 index 0000000000..ce7ed6966d --- /dev/null +++ b/rust-lib/flowy-user/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "flowy-user" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +derive_more = {version = "0.99", features = ["display"]} +flowy-sys = { path = "../flowy-sys" } +flowy-log = { path = "../flowy-log" } \ No newline at end of file diff --git a/rust-lib/flowy-user/src/error.rs b/rust-lib/flowy-user/src/error.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/rust-lib/flowy-user/src/error.rs @@ -0,0 +1 @@ + diff --git a/rust-lib/flowy-user/src/event.rs b/rust-lib/flowy-user/src/event.rs new file mode 100644 index 0000000000..230dfe94e1 --- /dev/null +++ b/rust-lib/flowy-user/src/event.rs @@ -0,0 +1,10 @@ +use derive_more::Display; + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash)] +pub enum UserEvent { + #[display(fmt = "AuthCheck")] + AuthCheck = 0, + SignIn = 1, + SignUp = 2, + SignOut = 3, +} diff --git a/rust-lib/flowy-user/src/handlers/auth.rs b/rust-lib/flowy-user/src/handlers/auth.rs new file mode 100644 index 0000000000..50b2b55ab7 --- /dev/null +++ b/rust-lib/flowy-user/src/handlers/auth.rs @@ -0,0 +1,2 @@ +// #[tracing::instrument(name = "Adding a new subscriber")] +pub async fn user_check() -> String { "".to_owned() } diff --git a/rust-lib/flowy-user/src/handlers/mod.rs b/rust-lib/flowy-user/src/handlers/mod.rs new file mode 100644 index 0000000000..ca51de07ab --- /dev/null +++ b/rust-lib/flowy-user/src/handlers/mod.rs @@ -0,0 +1,3 @@ +mod auth; + +pub use auth::*; diff --git a/rust-lib/flowy-user/src/lib.rs b/rust-lib/flowy-user/src/lib.rs new file mode 100644 index 0000000000..41ae48f870 --- /dev/null +++ b/rust-lib/flowy-user/src/lib.rs @@ -0,0 +1,4 @@ +mod error; +mod event; +mod handlers; +pub mod module; diff --git a/rust-lib/flowy-user/src/module.rs b/rust-lib/flowy-user/src/module.rs new file mode 100644 index 0000000000..22f6d05e2f --- /dev/null +++ b/rust-lib/flowy-user/src/module.rs @@ -0,0 +1,10 @@ +use crate::{event::UserEvent::*, handlers::*}; +use flowy_sys::prelude::*; + +pub fn create() -> Module { + Module::new() + .event(AuthCheck, user_check) + .event(SignIn, user_check) + .event(SignUp, user_check) + .event(SignOut, user_check) +}