mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
add flowy-user crate & config user module
This commit is contained in:
parent
6fe196e97f
commit
4e45b1bdfe
@ -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" />
|
||||
|
@ -4,6 +4,7 @@ members = [
|
||||
"flowy-sdk",
|
||||
"dart-ffi",
|
||||
"flowy-log",
|
||||
"flowy-user",
|
||||
]
|
||||
|
||||
[profile.dev]
|
||||
|
@ -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'");
|
||||
}
|
||||
|
@ -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" }
|
@ -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)
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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() }
|
||||
}
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -1,2 +1,2 @@
|
||||
mod helper;
|
||||
mod module_event;
|
||||
mod module;
|
||||
|
23
rust-lib/flowy-sys/tests/api/module.rs
Normal file
23
rust-lib/flowy-sys/tests/api/module.rs
Normal 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();
|
||||
});
|
||||
}
|
@ -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();
|
||||
});
|
||||
}
|
11
rust-lib/flowy-user/Cargo.toml
Normal file
11
rust-lib/flowy-user/Cargo.toml
Normal 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" }
|
1
rust-lib/flowy-user/src/error.rs
Normal file
1
rust-lib/flowy-user/src/error.rs
Normal file
@ -0,0 +1 @@
|
||||
|
10
rust-lib/flowy-user/src/event.rs
Normal file
10
rust-lib/flowy-user/src/event.rs
Normal 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,
|
||||
}
|
2
rust-lib/flowy-user/src/handlers/auth.rs
Normal file
2
rust-lib/flowy-user/src/handlers/auth.rs
Normal file
@ -0,0 +1,2 @@
|
||||
// #[tracing::instrument(name = "Adding a new subscriber")]
|
||||
pub async fn user_check() -> String { "".to_owned() }
|
3
rust-lib/flowy-user/src/handlers/mod.rs
Normal file
3
rust-lib/flowy-user/src/handlers/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
mod auth;
|
||||
|
||||
pub use auth::*;
|
4
rust-lib/flowy-user/src/lib.rs
Normal file
4
rust-lib/flowy-user/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod error;
|
||||
mod event;
|
||||
mod handlers;
|
||||
pub mod module;
|
10
rust-lib/flowy-user/src/module.rs
Normal file
10
rust-lib/flowy-user/src/module.rs
Normal 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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user