diff --git a/.run/ProtoBuf_Gen.run.xml b/.run/ProtoBuf_Gen.run.xml new file mode 100644 index 0000000000..2fdf466875 --- /dev/null +++ b/.run/ProtoBuf_Gen.run.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/.run/Run backend.run.xml b/.run/Run backend.run.xml new file mode 100644 index 0000000000..840a367809 --- /dev/null +++ b/.run/Run backend.run.xml @@ -0,0 +1,18 @@ + + + + \ No newline at end of file diff --git a/.run/dart-event.run.xml b/.run/dart-event.run.xml new file mode 100644 index 0000000000..71ac27e8e7 --- /dev/null +++ b/.run/dart-event.run.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/backend/.dockerignore b/backend/.dockerignore index 1719710ae1..5ebf0cb3f8 100644 --- a/backend/.dockerignore +++ b/backend/.dockerignore @@ -7,4 +7,5 @@ tests/ Dockerfile scripts/ migrations/ -app_flowy/ \ No newline at end of file +app_flowy/ +rust-lib/target/ \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile index b642fe993f..dc50419889 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,15 +1,58 @@ -# We use the latest Rust stable release as base image + FROM rust:1.53.0 # Let's switch our working directory to `app` (equivalent to `cd app`) # The `app` folder will be created for us by Docker in case it does not # exist already. WORKDIR /app -# Copy all files from our working environment to our Docker image COPY . . -# Let's build our binary! -# We'll use the release profile to make it fast + WORKDIR /app/backend +ENV SQLX_OFFLINE true +ENV APP_ENVIRONMENT production RUN cargo build --release + # When `docker run` is executed, launch the binary! ENTRYPOINT ["./target/release/backend"] + +# + + + +## We use the latest Rust stable release as base image +#FROM lukemathwalker/cargo-chef:latest-rust-1.53.0 as planner +#WORKDIR /app +#COPY . . +# +#WORKDIR /app/backend +#RUN cargo chef prepare --recipe-path recipe.json +# +#FROM lukemathwalker/cargo-chef:latest-rust-1.53.0 as cacher +#WORKDIR /app/backend +#COPY --from=planner /app/backend/recipe.json recipe.json +## Build our project dependencies, not our application! +#RUN cargo chef cook --release --recipe-path recipe.json +# +#FROM rust:1.53.0 AS builder +#WORKDIR /app/backend +## Copy over the cached dependencies +#COPY --from=cacher /app/backend/target target +#COPY --from=cacher /usr/local/cargo /usr/local/cargo +#COPY . . +# +#ENV SQLX_OFFLINE true +#RUN cargo build --release --bin backend +# +# +#FROM debian:buster-slim AS runtime +#WORKDIR /app/backend +#RUN apt-get update -y \ +# && apt-get install -y --no-install-recommends openssl \ +# # Clean up +# && apt-get autoremove -y \ +# && apt-get clean -y \ +# && rm -rf /var/lib/apt/lists/* +#COPY --from=builder /app/backend/target/release/backend backend +##COPY configuration configuration +#ENV APP_ENVIRONMENT production +#ENTRYPOINT ["./backend"] diff --git a/backend/configuration/production.yaml b/backend/configuration/production.yaml index cd4608ab4f..1de1c6bb54 100644 --- a/backend/configuration/production.yaml +++ b/backend/configuration/production.yaml @@ -1,4 +1,4 @@ application: host: 0.0.0.0 database: - require_ssl: true + require_ssl: false diff --git a/backend/doc/database_setup.md b/backend/doc/database_setup.md index 83c82cbde0..01a701c604 100644 --- a/backend/doc/database_setup.md +++ b/backend/doc/database_setup.md @@ -27,4 +27,8 @@ export DB_PORT=5433 ![img_1.png](img_1.png) -[Docker command](https://docs.docker.com/engine/reference/commandline/builder_prune/) \ No newline at end of file +[Docker command](https://docs.docker.com/engine/reference/commandline/builder_prune/) + +### Run +By default, Docker images do not expose their ports to the underlying host machine. We need to do it explicitly using the -p flag. +`docker run -p 8000:8000 backend` \ No newline at end of file diff --git a/backend/src/application.rs b/backend/src/application.rs index ec617cd2fd..0f8a895e93 100644 --- a/backend/src/application.rs +++ b/backend/src/application.rs @@ -63,7 +63,10 @@ async fn init_app_context(configuration: &Settings) -> Arc { let pg_pool = Arc::new( get_connection_pool(&configuration.database) .await - .expect("Failed to connect to Postgres."), + .expect(&format!( + "Failed to connect to Postgres {:?}.", + configuration.database + )), ); let ws_server = WSServer::new().start(); @@ -77,7 +80,7 @@ async fn init_app_context(configuration: &Settings) -> Arc { pub async fn get_connection_pool(configuration: &DatabaseSettings) -> Result { PgPoolOptions::new() - .connect_timeout(std::time::Duration::from_secs(2)) + .connect_timeout(std::time::Duration::from_secs(5)) .connect_with(configuration.with_db()) .await } diff --git a/backend/src/config/configuration.rs b/backend/src/config/configuration.rs index d76de5463f..48f26eb0f1 100644 --- a/backend/src/config/configuration.rs +++ b/backend/src/config/configuration.rs @@ -8,15 +8,22 @@ pub struct Settings { pub application: ApplicationSettings, } +// We are using 127.0.0.1 as our host in address, we are instructing our +// application to only accept connections coming from the same machine. However, +// request from the hose machine which is not seen as local by our Docker image. +// +// Using 0.0.0.0 as host to instruct our application to accept connections from +// any network interface. So using 127.0.0.1 for our local development and set +// it to 0.0.0.0 in our Docker images. +// #[derive(serde::Deserialize, Clone)] pub struct ApplicationSettings { #[serde(deserialize_with = "deserialize_number_from_string")] pub port: u16, pub host: String, - pub base_url: String, } -#[derive(serde::Deserialize, Clone)] +#[derive(serde::Deserialize, Clone, Debug)] pub struct DatabaseSettings { pub username: String, pub password: String, diff --git a/backend/src/routers/user.rs b/backend/src/routers/user.rs index f9b90a8710..fb33abf10b 100644 --- a/backend/src/routers/user.rs +++ b/backend/src/routers/user.rs @@ -14,11 +14,9 @@ pub async fn register( _request: HttpRequest, payload: Payload, auth: Data>, -) -> Result { +) -> Result { let params: SignUpParams = parse_from_payload(payload).await?; - let _ = auth.sign_up(params).await?; - - let resp = FlowyResponse::success(); + let resp = auth.sign_up(params).await?; Ok(resp.into()) } diff --git a/backend/src/user_service/auth.rs b/backend/src/user_service/auth.rs index 3e590cfc00..dd8cbe76e9 100644 --- a/backend/src/user_service/auth.rs +++ b/backend/src/user_service/auth.rs @@ -1,5 +1,5 @@ use chrono::Utc; -use flowy_net::response::{ServerCode, ServerError}; +use flowy_net::response::{FlowyResponse, ServerCode, ServerError}; use flowy_user::{entities::SignUpResponse, protobuf::SignUpParams}; use sqlx::PgPool; use std::sync::Arc; @@ -11,15 +11,16 @@ pub struct Auth { impl Auth { pub fn new(db_pool: Arc) -> Self { Self { db_pool } } - pub async fn sign_up(&self, params: SignUpParams) -> Result { + pub async fn sign_up(&self, params: SignUpParams) -> Result { // email exist? // generate user id + let uuid = uuid::Uuid::new_v4(); let result = sqlx::query!( r#" INSERT INTO user_table (id, email, name, create_time, password) VALUES ($1, $2, $3, $4, $5) "#, - uuid::Uuid::new_v4(), + uuid, params.email, params.name, Utc::now(), @@ -28,11 +29,14 @@ impl Auth { .execute(self.db_pool.as_ref()) .await; - let response = SignUpResponse { - uid: "".to_string(), - name: "".to_string(), - email: "".to_string(), + let data = SignUpResponse { + uid: uuid.to_string(), + name: params.name, + email: params.email, }; + + let response = FlowyResponse::from(data, "", ServerCode::Success)?; + Ok(response) } diff --git a/rust-lib/Cargo.toml b/rust-lib/Cargo.toml index 5815cabc35..75b7f6b5f1 100644 --- a/rust-lib/Cargo.toml +++ b/rust-lib/Cargo.toml @@ -19,5 +19,7 @@ members = [ "flowy-net", ] +exclude = ["../backend"] + [profile.dev] split-debuginfo = "unpacked" diff --git a/rust-lib/flowy-dispatch/src/byte_trait.rs b/rust-lib/flowy-dispatch/src/byte_trait.rs index 531d4aab7a..beb6e4a614 100644 --- a/rust-lib/flowy-dispatch/src/byte_trait.rs +++ b/rust-lib/flowy-dispatch/src/byte_trait.rs @@ -1,6 +1,6 @@ use crate::errors::{DispatchError, InternalError}; use bytes::Bytes; -use protobuf::ProtobufError; + use std::convert::TryFrom; // To bytes diff --git a/rust-lib/flowy-dispatch/src/errors/errors.rs b/rust-lib/flowy-dispatch/src/errors/errors.rs index 051d5bfd26..4ca65400af 100644 --- a/rust-lib/flowy-dispatch/src/errors/errors.rs +++ b/rust-lib/flowy-dispatch/src/errors/errors.rs @@ -5,7 +5,7 @@ use crate::{ }; use bytes::Bytes; use dyn_clone::DynClone; -use protobuf::ProtobufError; + use serde::{Serialize, Serializer}; use std::fmt; use tokio::{sync::mpsc::error::SendError, task::JoinError}; diff --git a/rust-lib/flowy-dispatch/src/response/response.rs b/rust-lib/flowy-dispatch/src/response/response.rs index 95f26c047c..8208589242 100644 --- a/rust-lib/flowy-dispatch/src/response/response.rs +++ b/rust-lib/flowy-dispatch/src/response/response.rs @@ -1,7 +1,7 @@ use crate::{ byte_trait::FromBytes, data::Data, - errors::{DispatchError, InternalError}, + errors::DispatchError, request::{EventRequest, Payload}, response::Responder, }; diff --git a/rust-lib/flowy-net/src/config.rs b/rust-lib/flowy-net/src/config.rs index 8440c3996b..51aef47acc 100644 --- a/rust-lib/flowy-net/src/config.rs +++ b/rust-lib/flowy-net/src/config.rs @@ -1,6 +1,6 @@ use lazy_static::lazy_static; -pub const HOST: &'static str = "http://0.0.0.0:3030"; +pub const HOST: &'static str = "http://localhost:8000"; lazy_static! { pub static ref SIGN_UP_URL: String = format!("{}/user/register", HOST); diff --git a/rust-lib/flowy-net/src/errors/errors.rs b/rust-lib/flowy-net/src/errors/errors.rs deleted file mode 100644 index 6a7b431a7f..0000000000 --- a/rust-lib/flowy-net/src/errors/errors.rs +++ /dev/null @@ -1,45 +0,0 @@ -use crate::response::FlowyResponse; -use protobuf::ProtobufError; -use std::fmt::{Formatter, Write}; - -// #[derive(Debug)] -// pub struct ServerError { -// code: ErrorCode -// } -// -// pub enum ErrorCode { -// InternalError(String), -// ProtobufError(ProtobufError), -// BadRequest(FlowyResponse), -// Unauthorized, -// } -// -// -// impl std::fmt::Display for ErrorCode { -// fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { -// match self { -// ErrorCode::InternalError(_) => f.write_str("Internal Server -// Error"), ErrorCode::ProtobufError(err) => -// f.write_str(&format!("protobuf error: {}", err)), -// ErrorCode::BadRequest(request) => { let msg = format!("Bad -// Request: {:?}", request); f.write_str(&msg) -// }, -// ErrorCode::Unauthorized => f.write_str("Unauthorized"), -// } -// } -// } - -// impl std::convert::From for ServerCode { -// fn from(err: ProtobufError) -> Self { ServerCode::ProtobufError(err) } -// } -// -// impl std::convert::From for ServerError { -// fn from(error: reqwest::Error) -> Self { -// let msg = format!("{:?}", error); -// ServerError::InternalError(msg) -// } -// } -// -// impl std::convert::From for ServerError { -// fn from(error: String) -> Self { ServerError::InternalError(error) } -// } diff --git a/rust-lib/flowy-net/src/errors/mod.rs b/rust-lib/flowy-net/src/errors/mod.rs deleted file mode 100644 index 852f5c0f5e..0000000000 --- a/rust-lib/flowy-net/src/errors/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod errors; - -pub use errors::*; diff --git a/rust-lib/flowy-net/src/lib.rs b/rust-lib/flowy-net/src/lib.rs index a0b6d841ce..2426021c58 100644 --- a/rust-lib/flowy-net/src/lib.rs +++ b/rust-lib/flowy-net/src/lib.rs @@ -1,6 +1,4 @@ -pub mod errors; -pub mod future; - pub mod config; +pub mod future; pub mod request; pub mod response; diff --git a/rust-lib/flowy-net/src/request/request.rs b/rust-lib/flowy-net/src/request/request.rs index 5c3532f5e4..1617063649 100644 --- a/rust-lib/flowy-net/src/request/request.rs +++ b/rust-lib/flowy-net/src/request/request.rs @@ -1,23 +1,13 @@ -use crate::{future::ResultFuture, response::ServerError}; +use crate::response::{FlowyResponse, ServerCode, ServerError}; use bytes::Bytes; +use hyper::http; use protobuf::{Message, ProtobufError}; -use reqwest::{Client, Error, Response}; +use reqwest::{Client, Response}; use std::{ convert::{TryFrom, TryInto}, time::Duration, }; -use hyper::{StatusCode, http}; -use tokio::sync::{oneshot, oneshot::error::RecvError}; -use crate::response::ServerCode; - -// pub async fn http_post(url: &str, data: T1) -> ResultFuture where -// T1: TryInto + Send + Sync + 'static, -// T2: TryFrom + Send + Sync + 'static, -// { -// let url = url.to_owned(); -// ResultFuture::new(async move { post(url, data).await }) -// } +use tokio::sync::oneshot; pub async fn http_post(url: &str, data: T1) -> Result where @@ -37,9 +27,9 @@ where let response = rx.await??; if response.status() == http::StatusCode::OK { let response_bytes = response.bytes().await?; - let data = T2::try_from(response_bytes)?; + let flowy_resp: FlowyResponse = serde_json::from_slice(&response_bytes).unwrap(); + let data = T2::try_from(flowy_resp.data)?; Ok(data) - } else { Err(ServerError { code: ServerCode::InternalError, diff --git a/rust-lib/flowy-net/src/response/response.rs b/rust-lib/flowy-net/src/response/response.rs index 7b2b7108ab..ef5603978a 100644 --- a/rust-lib/flowy-net/src/response/response.rs +++ b/rust-lib/flowy-net/src/response/response.rs @@ -1,6 +1,7 @@ -use serde::{Serialize, __private::Formatter}; +use bytes::Bytes; +use serde::{Deserialize, Serialize, __private::Formatter}; use serde_repr::*; -use std::{error::Error, fmt}; +use std::{convert::TryInto, error::Error, fmt}; use tokio::sync::oneshot::error::RecvError; #[derive(Debug)] @@ -16,11 +17,11 @@ impl std::fmt::Display for ServerError { } } -impl std::convert::From<&ServerError> for FlowyResponse { +impl std::convert::From<&ServerError> for FlowyResponse { fn from(error: &ServerError) -> Self { FlowyResponse { msg: error.msg.clone(), - data: None, + data: Bytes::from(vec![]), code: error.code.clone(), } } @@ -43,15 +44,15 @@ pub enum ServerCode { ConnectCancel = 11, } -#[derive(Debug, Serialize)] -pub struct FlowyResponse { +#[derive(Debug, Serialize, Deserialize)] +pub struct FlowyResponse { pub msg: String, - pub data: Option, + pub data: Bytes, pub code: ServerCode, } -impl FlowyResponse { - pub fn new(data: Option, msg: &str, code: ServerCode) -> Self { +impl FlowyResponse { + pub fn new(data: Bytes, msg: &str, code: ServerCode) -> Self { FlowyResponse { msg: msg.to_owned(), data, @@ -59,16 +60,13 @@ impl FlowyResponse { } } - pub fn from_data(data: T, msg: &str, code: ServerCode) -> Self { - Self::new(Some(data), msg, code) - } -} - -impl FlowyResponse { - pub fn success() -> Self { Self::from_msg("", ServerCode::Success) } - - pub fn from_msg(msg: &str, code: ServerCode) -> Self { - Self::new(Some("".to_owned()), msg, code) + pub fn from>( + data: T, + msg: &str, + code: ServerCode, + ) -> Result { + let bytes: Bytes = data.try_into()?; + Ok(Self::new(bytes, msg, code)) } } @@ -90,6 +88,16 @@ impl std::convert::From for ServerError { } } +impl std::convert::From for ServerError { + fn from(e: serde_json::Error) -> Self { + let msg = format!("Serial error: {:?}", e); + ServerError { + code: ServerCode::SerdeError, + msg, + } + } +} + impl std::convert::From for ServerError { fn from(error: reqwest::Error) -> Self { if error.is_timeout() { @@ -121,9 +129,7 @@ impl std::convert::From for ServerError { code = ServerCode::ConnectCancel; } - if hyper_error.is_timeout() { - - } + if hyper_error.is_timeout() {} ServerError { code, msg } }, diff --git a/rust-lib/flowy-net/src/response/response_http.rs b/rust-lib/flowy-net/src/response/response_http.rs index 8c33bd6e11..689823bf2b 100644 --- a/rust-lib/flowy-net/src/response/response_http.rs +++ b/rust-lib/flowy-net/src/response/response_http.rs @@ -1,30 +1,14 @@ use crate::response::*; use actix_web::{body::Body, error::ResponseError, BaseHttpResponse, HttpResponse}; +use reqwest::StatusCode; use serde::Serialize; -impl ServerError { - fn http_response(&self) -> HttpResponse { - let resp: FlowyResponse = self.into(); - HttpResponse::Ok().json(resp) - } -} - impl ResponseError for ServerError { - fn error_response(&self) -> HttpResponse { self.http_response().into() } -} - -impl std::convert::Into for FlowyResponse { - fn into(self) -> HttpResponse { - match serde_json::to_string(&self) { - Ok(body) => HttpResponse::Ok().body(Body::from(body)), - Err(e) => { - let msg = format!("Serial error: {:?}", e); - ServerError { - code: ServerCode::SerdeError, - msg, - } - .error_response() - }, - } + fn error_response(&self) -> HttpResponse { + let response: FlowyResponse = self.into(); + response.into() } } +impl std::convert::Into for FlowyResponse { + fn into(self) -> HttpResponse { HttpResponse::Ok().json(self) } +} diff --git a/rust-lib/flowy-net/src/response/response_serde.rs b/rust-lib/flowy-net/src/response/response_serde.rs index b81b61a0cd..f8a7962e8b 100644 --- a/rust-lib/flowy-net/src/response/response_serde.rs +++ b/rust-lib/flowy-net/src/response/response_serde.rs @@ -1,128 +1,129 @@ -use crate::response::{FlowyResponse, ServerCode}; -use serde::{ - de::{self, MapAccess, Visitor}, - Deserialize, - Deserializer, - Serialize, -}; -use std::{fmt, marker::PhantomData, str::FromStr}; - -pub trait ServerData<'a>: Serialize + Deserialize<'a> + FromStr {} -impl<'de, T: ServerData<'de>> Deserialize<'de> for FlowyResponse { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct ServerResponseVisitor(PhantomData T>); - impl<'de, T> Visitor<'de> for ServerResponseVisitor - where - T: ServerData<'de>, - { - type Value = FlowyResponse; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("struct Duration") - } - - fn visit_map(self, mut map: V) -> Result - where - V: MapAccess<'de>, - { - let mut msg = None; - let mut data: Option = None; - let mut code: Option = None; - while let Some(key) = map.next_key()? { - match key { - "msg" => { - if msg.is_some() { - return Err(de::Error::duplicate_field("msg")); - } - msg = Some(map.next_value()?); - }, - "code" => { - if code.is_some() { - return Err(de::Error::duplicate_field("code")); - } - code = Some(map.next_value()?); - }, - "data" => { - if data.is_some() { - return Err(de::Error::duplicate_field("data")); - } - data = match MapAccess::next_value::>(&mut map) { - Ok(wrapper) => wrapper.value, - Err(err) => return Err(err), - }; - }, - _ => panic!(), - } - } - let msg = msg.ok_or_else(|| de::Error::missing_field("msg"))?; - let code = code.ok_or_else(|| de::Error::missing_field("code"))?; - Ok(Self::Value::new(data, msg, code)) - } - } - const FIELDS: &'static [&'static str] = &["msg", "code", "data"]; - deserializer.deserialize_struct( - "ServerResponse", - FIELDS, - ServerResponseVisitor(PhantomData), - ) - } -} - -struct DeserializeWith<'de, T: ServerData<'de>> { - value: Option, - phantom: PhantomData<&'de ()>, -} - -impl<'de, T: ServerData<'de>> Deserialize<'de> for DeserializeWith<'de, T> { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Ok(DeserializeWith { - value: match string_or_data(deserializer) { - Ok(val) => val, - Err(e) => return Err(e), - }, - phantom: PhantomData, - }) - } -} - -fn string_or_data<'de, D, T>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, - T: ServerData<'de>, -{ - struct StringOrData(PhantomData T>); - impl<'de, T: ServerData<'de>> Visitor<'de> for StringOrData { - type Value = Option; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("string or struct impl deserialize") - } - - fn visit_str(self, value: &str) -> Result - where - E: de::Error, - { - match FromStr::from_str(value) { - Ok(val) => Ok(Some(val)), - Err(_e) => Ok(None), - } - } - - fn visit_map(self, map: M) -> Result - where - M: MapAccess<'de>, - { - match Deserialize::deserialize(de::value::MapAccessDeserializer::new(map)) { - Ok(val) => Ok(Some(val)), - Err(e) => Err(e), - } - } - } - deserializer.deserialize_any(StringOrData(PhantomData)) -} +// use crate::response::{FlowyResponse, ServerCode}; +// use serde::{ +// de::{self, MapAccess, Visitor}, +// Deserialize, +// Deserializer, +// Serialize, +// }; +// use std::{fmt, marker::PhantomData, str::FromStr}; +// +// pub trait ServerData<'a>: Serialize + Deserialize<'a> + FromStr {} +// impl<'de, T: ServerData<'de>> Deserialize<'de> for FlowyResponse { +// fn deserialize(deserializer: D) -> Result +// where +// D: Deserializer<'de>, +// { +// struct ServerResponseVisitor(PhantomData T>); +// impl<'de, T> Visitor<'de> for ServerResponseVisitor +// where +// T: ServerData<'de>, +// { +// type Value = FlowyResponse; +// +// fn expecting(&self, formatter: &mut fmt::Formatter) -> +// fmt::Result { formatter.write_str("struct Duration") +// } +// +// fn visit_map(self, mut map: V) -> Result where +// V: MapAccess<'de>, +// { +// let mut msg = None; +// let mut data: Option = None; +// let mut code: Option = None; +// while let Some(key) = map.next_key()? { +// match key { +// "msg" => { +// if msg.is_some() { +// return +// Err(de::Error::duplicate_field("msg")); } +// msg = Some(map.next_value()?); +// }, +// "code" => { +// if code.is_some() { +// return +// Err(de::Error::duplicate_field("code")); } +// code = Some(map.next_value()?); +// }, +// "data" => { +// if data.is_some() { +// return +// Err(de::Error::duplicate_field("data")); } +// data = match +// MapAccess::next_value::>(&mut map) { +// Ok(wrapper) => wrapper.value, Err(err) => +// return Err(err), }; +// }, +// _ => panic!(), +// } +// } +// let msg = msg.ok_or_else(|| +// de::Error::missing_field("msg"))?; let code = +// code.ok_or_else(|| de::Error::missing_field("code"))?; +// Ok(Self::Value::new(data, msg, code)) } +// } +// const FIELDS: &'static [&'static str] = &["msg", "code", "data"]; +// deserializer.deserialize_struct( +// "ServerResponse", +// FIELDS, +// ServerResponseVisitor(PhantomData), +// ) +// } +// } +// +// struct DeserializeWith<'de, T: ServerData<'de>> { +// value: Option, +// phantom: PhantomData<&'de ()>, +// } +// +// impl<'de, T: ServerData<'de>> Deserialize<'de> for DeserializeWith<'de, T> { +// fn deserialize(deserializer: D) -> Result +// where +// D: Deserializer<'de>, +// { +// Ok(DeserializeWith { +// value: match string_or_data(deserializer) { +// Ok(val) => val, +// Err(e) => return Err(e), +// }, +// phantom: PhantomData, +// }) +// } +// } +// +// fn string_or_data<'de, D, T>(deserializer: D) -> Result, D::Error> +// where +// D: Deserializer<'de>, +// T: ServerData<'de>, +// { +// struct StringOrData(PhantomData T>); +// impl<'de, T: ServerData<'de>> Visitor<'de> for StringOrData { +// type Value = Option; +// +// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +// formatter.write_str("string or struct impl deserialize") +// } +// +// fn visit_str(self, value: &str) -> Result +// where +// E: de::Error, +// { +// match FromStr::from_str(value) { +// Ok(val) => Ok(Some(val)), +// Err(_e) => Ok(None), +// } +// } +// +// fn visit_map(self, map: M) -> Result +// where +// M: MapAccess<'de>, +// { +// match +// Deserialize::deserialize(de::value::MapAccessDeserializer::new(map)) { +// Ok(val) => Ok(Some(val)), +// Err(e) => Err(e), +// } +// } +// } +// deserializer.deserialize_any(StringOrData(PhantomData)) +// } diff --git a/rust-lib/flowy-observable/src/dart/stream_sender.rs b/rust-lib/flowy-observable/src/dart/stream_sender.rs index 3a8d019ff4..9d6b974bd0 100644 --- a/rust-lib/flowy-observable/src/dart/stream_sender.rs +++ b/rust-lib/flowy-observable/src/dart/stream_sender.rs @@ -40,7 +40,7 @@ impl RustStreamSender { } } - pub fn post(observable_subject: ObservableSubject) -> Result<(), String> { + pub fn post(_observable_subject: ObservableSubject) -> Result<(), String> { #[cfg(feature = "dart")] match R2F_STREAM_SENDER.read() { Ok(stream) => stream.inner_post(observable_subject), diff --git a/rust-lib/flowy-user/src/entities/sign_up.rs b/rust-lib/flowy-user/src/entities/sign_up.rs index a1395c51c2..f07bc64af0 100644 --- a/rust-lib/flowy-user/src/entities/sign_up.rs +++ b/rust-lib/flowy-user/src/entities/sign_up.rs @@ -1,6 +1,6 @@ use crate::{ entities::parser::*, - errors::{ErrorBuilder, UserErrCode, UserError}, + errors::{ErrorBuilder, UserError}, }; use flowy_derive::ProtoBuf; use std::convert::TryInto; diff --git a/rust-lib/flowy-user/src/services/user/user_server.rs b/rust-lib/flowy-user/src/services/user/user_server.rs index 98cdafd04d..1dfa9c153e 100644 --- a/rust-lib/flowy-user/src/services/user/user_server.rs +++ b/rust-lib/flowy-user/src/services/user/user_server.rs @@ -3,7 +3,6 @@ use crate::{ errors::{ErrorBuilder, UserErrCode, UserError}, }; -use bytes::Bytes; use flowy_net::{config::SIGN_UP_URL, future::ResultFuture, request::http_post}; use std::sync::Arc; diff --git a/rust-lib/flowy-user/tests/event/helper.rs b/rust-lib/flowy-user/tests/event/helper.rs index ba0d12ece5..388ad02003 100644 --- a/rust-lib/flowy-user/tests/event/helper.rs +++ b/rust-lib/flowy-user/tests/event/helper.rs @@ -5,7 +5,6 @@ pub use flowy_test::prelude::{random_valid_email, valid_password}; pub(crate) fn invalid_email_test_case() -> Vec { // https://gist.github.com/cjaoude/fd9910626629b53c4d25 vec![ - "", "annie@", "annie@gmail@", "#@%^%#$@#$@#.com", @@ -31,7 +30,7 @@ pub(crate) fn invalid_email_test_case() -> Vec { } pub(crate) fn invalid_password_test_case() -> Vec { - vec!["", "123456", "1234".repeat(100).as_str()] + vec!["123456", "1234".repeat(100).as_str()] .iter() .map(|s| s.to_string()) .collect::>() diff --git a/rust-lib/flowy-user/tests/event/sign_in_test.rs b/rust-lib/flowy-user/tests/event/sign_in_test.rs index 28185bfec4..2f9bf585dd 100644 --- a/rust-lib/flowy-user/tests/event/sign_in_test.rs +++ b/rust-lib/flowy-user/tests/event/sign_in_test.rs @@ -35,7 +35,7 @@ fn sign_in_with_invalid_email() { .sync_send() .error() .code, - UserErrCode::EmailInvalid + UserErrCode::EmailFormatInvalid ); } } @@ -56,7 +56,7 @@ fn sign_in_with_invalid_password() { .sync_send() .error() .code, - UserErrCode::PasswordInvalid + UserErrCode::PasswordFormatInvalid ); } } diff --git a/rust-lib/flowy-user/tests/event/sign_up_test.rs b/rust-lib/flowy-user/tests/event/sign_up_test.rs index 5e74e3ffcf..2c25268e6f 100644 --- a/rust-lib/flowy-user/tests/event/sign_up_test.rs +++ b/rust-lib/flowy-user/tests/event/sign_up_test.rs @@ -35,7 +35,7 @@ fn sign_up_with_invalid_email() { .sync_send() .error() .code, - UserErrCode::EmailInvalid + UserErrCode::EmailFormatInvalid ); } } @@ -56,7 +56,7 @@ fn sign_up_with_invalid_password() { .sync_send() .error() .code, - UserErrCode::PasswordInvalid + UserErrCode::PasswordFormatInvalid ); } } diff --git a/rust-lib/flowy-user/tests/event/user_update_test.rs b/rust-lib/flowy-user/tests/event/user_update_test.rs index 10040340c4..3382408853 100644 --- a/rust-lib/flowy-user/tests/event/user_update_test.rs +++ b/rust-lib/flowy-user/tests/event/user_update_test.rs @@ -86,7 +86,7 @@ fn user_update_with_invalid_email() { .sync_send() .error() .code, - UserErrCode::EmailInvalid + UserErrCode::EmailFormatInvalid ); } } @@ -111,7 +111,7 @@ fn user_update_with_invalid_password() { .sync_send() .error() .code, - UserErrCode::PasswordInvalid + UserErrCode::PasswordFormatInvalid ); } } @@ -135,6 +135,6 @@ fn user_update_with_invalid_name() { .sync_send() .error() .code, - UserErrCode::UserNameInvalid + UserErrCode::UserIdInvalid ); } diff --git a/rust-lib/flowy-user/tests/server/user_test.rs b/rust-lib/flowy-user/tests/server/user_test.rs index 9f34ecba5e..b4322e46f1 100644 --- a/rust-lib/flowy-user/tests/server/user_test.rs +++ b/rust-lib/flowy-user/tests/server/user_test.rs @@ -10,4 +10,5 @@ async fn user_register_test() { password: "123".to_string(), }; let result = server.sign_up(params).await.unwrap(); + println!("{:?}", result); } diff --git a/rust-lib/flowy-workspace/src/observable/observable.rs b/rust-lib/flowy-workspace/src/observable/observable.rs index ae5ff30880..5db04f5339 100644 --- a/rust-lib/flowy-workspace/src/observable/observable.rs +++ b/rust-lib/flowy-workspace/src/observable/observable.rs @@ -1,6 +1,6 @@ use bytes::Bytes; use flowy_derive::ProtoBuf_Enum; -use flowy_dispatch::prelude::{DispatchError, ToBytes}; +use flowy_dispatch::prelude::ToBytes; use flowy_observable::{dart::RustStreamSender, entities::ObservableSubject}; const OBSERVABLE_CATEGORY: &'static str = "Workspace"; diff --git a/scripts/install_tool.sh b/scripts/install_tool.sh index fa73862c88..b32b425a8e 100755 --- a/scripts/install_tool.sh +++ b/scripts/install_tool.sh @@ -9,6 +9,7 @@ rustup component add rustfmt cargo install cargo-expand cargo install cargo-watch cargo install cargo-cache +cargo install bunyan #protobuf code gen env brew install protobuf@3.13