add flowy-user crate & config user module

This commit is contained in:
appflowy 2021-06-29 16:52:29 +08:00
parent 6fe196e97f
commit 4e45b1bdfe
21 changed files with 144 additions and 57 deletions

View File

@ -10,6 +10,7 @@
<sourceFolder url="file://$MODULE_DIR$/rust-lib/dart-ffi/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-log/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-sdk/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/rust-lib/flowy-user/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/.pub" />
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/af_protobuf/build" />

View File

@ -4,6 +4,7 @@ members = [
"flowy-sdk",
"dart-ffi",
"flowy-log",
"flowy-user",
]
[profile.dev]

View File

@ -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'");
}

View File

@ -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" }
flowy-sys = { path = "../flowy-sys" }
flowy-log = { path = "../flowy-log" }

View File

@ -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<T: Display + Eq + Hash + Debug + Clone> std::convert::From<T> 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<H, T, R>(mut self, event: Event, handler: H) -> Self
pub fn event<E, H, T, R>(mut self, event: E, handler: H) -> Self
where
H: Handler<T, R>,
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)

View File

@ -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<Vec<u8>>,
}
impl EventRequest {
pub fn new(event: String) -> EventRequest {
pub fn new<E>(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 }

View File

@ -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<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 { ResponseData::Bytes(self.bytes().to_vec()) }
}
impl std::convert::Into<ResponseData> for &str {
fn into(self) -> ResponseData { self.to_string().into() }
}

View File

@ -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<T, E> Responder for Result<T, E>
where
T: Responder,
E: Into<SystemError>,
{
fn respond_to(self, request: &EventRequest) -> EventResponse {
match self {
Ok(val) => val.respond_to(request),
Err(e) => e.into().into(),
}
}
}

View File

@ -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<T: 'static> Service<CommandData<T>> for CommandSenderService {
impl<T> Service<CommandData<T>> for CommandSenderService
where
T: 'static,
{
type Response = EventResponse;
type Error = SystemError;
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
@ -109,7 +112,10 @@ where
service_factor_impl!(CommandSender);
impl<T> CommandSender<T> {
impl<T> CommandSender<T>
where
T: 'static,
{
pub fn new(module_map: ModuleMap) -> Self {
let (data_tx, data_rx) = unbounded_channel::<CommandData<T>>();
Self {
@ -135,14 +141,20 @@ impl<T> CommandSender<T> {
pub fn take_data_rx(&mut self) -> UnboundedReceiver<CommandData<T>> { self.data_rx.take().unwrap() }
}
pub struct CommandSenderRunner<T: 'static> {
pub struct CommandSenderRunner<T>
where
T: 'static,
{
module_map: ModuleMap,
data_rx: UnboundedReceiver<CommandData<T>>,
}
service_factor_impl!(CommandSenderRunner);
impl<T: 'static> CommandSenderRunner<T> {
impl<T> CommandSenderRunner<T>
where
T: 'static,
{
pub fn new(module_map: ModuleMap, data_rx: UnboundedReceiver<CommandData<T>>) -> Self {
Self { module_map, data_rx }
}

View File

@ -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<F, S, T>(module_factory: F, sender_factory: S) -> SystemRunner
where
// E: Into<Event<E>> + Eq + Hash + Debug + Clone + 'static,
F: FnOnce() -> Vec<Module>,
S: FnOnce(ModuleMap) -> CommandSenderRunner<T>,
T: 'static,

View File

@ -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() {

View File

@ -1,2 +1,2 @@
mod helper;
mod module_event;
mod module;

View File

@ -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();
});
}

View File

@ -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();
});
}

View File

@ -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" }

View File

@ -0,0 +1 @@

View File

@ -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,
}

View File

@ -0,0 +1,2 @@
// #[tracing::instrument(name = "Adding a new subscriber")]
pub async fn user_check() -> String { "".to_owned() }

View File

@ -0,0 +1,3 @@
mod auth;
pub use auth::*;

View File

@ -0,0 +1,4 @@
mod error;
mod event;
mod handlers;
pub mod module;

View File

@ -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)
}