refactor attribute key

This commit is contained in:
appflowy 2021-09-13 15:51:13 +08:00
parent 26aa4e951e
commit 4d139b3f56
83 changed files with 480 additions and 1044 deletions

View File

@ -2,5 +2,5 @@ mod doc;
pub mod router;
mod sql_builder;
pub use doc::*;
pub(crate) use doc::*;
pub use router::*;

View File

@ -4,7 +4,7 @@ use flowy_workspace::protobuf::{App, CreateViewParams, View, ViewType, Workspace
use crate::{
service::workspace_service::{
app::sql_builder::NewAppSqlBuilder as AppBuilder,
view::{create_view_with_transaction, sql_builder::NewViewSqlBuilder as ViewBuilder},
view::create_view_with_transaction,
workspace::sql_builder::NewWorkspaceBuilder as WorkspaceBuilder,
},
sqlx_ext::{map_sqlx_error, DBTransaction},

View File

@ -156,13 +156,6 @@ impl TestServer {
.unwrap();
}
pub async fn update_doc(&self, params: UpdateDocParams) {
let url = format!("{}/api/doc", self.address);
let _ = update_doc_request(self.user_token(), params, &url)
.await
.unwrap();
}
pub async fn read_doc(&self, params: QueryDocParams) -> Option<Doc> {
let url = format!("{}/api/doc", self.address);
let doc = read_doc_request(self.user_token(), params, &url)

View File

@ -7,7 +7,6 @@ use flowy_workspace::entities::{
DeleteWorkspaceParams,
QueryWorkspaceParams,
UpdateWorkspaceParams,
Workspace,
},
};

View File

@ -1,4 +1,2 @@
mod model;
pub use model::*;

View File

@ -1,7 +1,7 @@
// Auto-generated, do not edit
// Auto-generated, do not edit
mod ffi_response;
pub use ffi_response::*;
mod ffi_response;
pub use ffi_response::*;
mod ffi_request;
pub use ffi_request::*;
mod ffi_request;
pub use ffi_request::*;

View File

@ -47,9 +47,7 @@ pub enum ASTData<'a> {
impl<'a> ASTData<'a> {
pub fn all_fields(&'a self) -> Box<dyn Iterator<Item = &'a ASTField<'a>> + 'a> {
match self {
ASTData::Enum(variants) => {
Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
},
ASTData::Enum(variants) => Box::new(variants.iter().flat_map(|variant| variant.fields.iter())),
ASTData::Struct(_, fields) => Box::new(fields.iter()),
}
}
@ -120,10 +118,7 @@ impl<'a> ASTField<'a> {
Some(inner) => {
match inner.primitive_ty {
PrimitiveTy::Map(map_info) => {
bracket_category = Some(BracketCategory::Map((
map_info.key.clone(),
map_info.value.clone(),
)))
bracket_category = Some(BracketCategory::Map((map_info.key.clone(), map_info.value.clone())))
},
PrimitiveTy::Vec => {
bracket_category = Some(BracketCategory::Vec);
@ -198,9 +193,7 @@ pub enum ASTStyle {
pub fn struct_from_ast<'a>(cx: &Ctxt, fields: &'a syn::Fields) -> (ASTStyle, Vec<ASTField<'a>>) {
match fields {
syn::Fields::Named(fields) => (ASTStyle::Struct, fields_from_ast(cx, &fields.named)),
syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
(ASTStyle::NewType, fields_from_ast(cx, &fields.unnamed))
},
syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => (ASTStyle::NewType, fields_from_ast(cx, &fields.unnamed)),
syn::Fields::Unnamed(fields) => (ASTStyle::Tuple, fields_from_ast(cx, &fields.unnamed)),
syn::Fields::Unit => (ASTStyle::Unit, Vec::new()),
}
@ -228,10 +221,7 @@ pub fn enum_from_ast<'a>(
.collect()
}
fn fields_from_ast<'a>(
cx: &Ctxt,
fields: &'a Punctuated<syn::Field, Token![,]>,
) -> Vec<ASTField<'a>> {
fn fields_from_ast<'a>(cx: &Ctxt, fields: &'a Punctuated<syn::Field, Token![,]>) -> Vec<ASTField<'a>> {
fields
.iter()
.enumerate()

View File

@ -22,12 +22,7 @@ impl AttrsContainer {
pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
let mut pb_struct_type = ASTAttr::none(cx, PB_STRUCT);
let mut pb_enum_type = ASTAttr::none(cx, PB_ENUM);
for meta_item in item
.attrs
.iter()
.flat_map(|attr| get_meta_items(cx, attr))
.flatten()
{
for meta_item in item.attrs.iter().flat_map(|attr| get_meta_items(cx, attr)).flatten() {
match &meta_item {
// Parse `#[pb(struct = "Type")]
Meta(NameValue(m)) if m.path == PB_STRUCT => {
@ -44,15 +39,8 @@ impl AttrsContainer {
},
Meta(meta_item) => {
let path = meta_item
.path()
.into_token_stream()
.to_string()
.replace(' ', "");
cx.error_spanned_by(
meta_item.path(),
format!("unknown pb container attribute `{}`", path),
);
let path = meta_item.path().into_token_stream().to_string().replace(' ', "");
cx.error_spanned_by(meta_item.path(), format!("unknown pb container attribute `{}`", path));
},
Lit(lit) => {
@ -103,8 +91,7 @@ impl<'c, T> ASTAttr<'c, T> {
let tokens = obj.into_token_stream();
if self.value.is_some() {
self.cx
.error_spanned_by(tokens, format!("duplicate attribute `{}`", self.name));
self.cx.error_spanned_by(tokens, format!("duplicate attribute `{}`", self.name));
} else {
self.tokens = tokens;
self.value = Some(value);
@ -160,12 +147,7 @@ impl ASTAttrField {
None => index.to_string(),
};
for meta_item in field
.attrs
.iter()
.flat_map(|attr| get_meta_items(cx, attr))
.flatten()
{
for meta_item in field.attrs.iter().flat_map(|attr| get_meta_items(cx, attr)).flatten() {
match &meta_item {
// Parse `#[pb(skip)]`
Meta(Path(word)) if word == SKIP => {
@ -200,15 +182,8 @@ impl ASTAttrField {
},
Meta(meta_item) => {
let path = meta_item
.path()
.into_token_stream()
.to_string()
.replace(' ', "");
cx.error_spanned_by(
meta_item.path(),
format!("unknown field attribute `{}`", path),
);
let path = meta_item.path().into_token_stream().to_string().replace(' ', "");
cx.error_spanned_by(meta_item.path(), format!("unknown field attribute `{}`", path));
},
Lit(lit) => {
@ -273,12 +248,7 @@ pub struct ASTEnumAttrVariant {
}
impl ASTEnumAttrVariant {
pub fn from_ast(
ctxt: &Ctxt,
ident: &syn::Ident,
variant: &syn::Variant,
enum_attrs: &Vec<syn::Attribute>,
) -> Self {
pub fn from_ast(ctxt: &Ctxt, ident: &syn::Ident, variant: &syn::Variant, enum_attrs: &Vec<syn::Attribute>) -> Self {
let enum_item_name = variant.ident.to_string();
let enum_name = ident.to_string();
let mut value = String::new();
@ -311,11 +281,7 @@ impl ASTEnumAttrVariant {
pub fn event_error(&self) -> String { self.event_attrs.error_ty.as_ref().unwrap().clone() }
}
fn get_event_attrs_from(
ctxt: &Ctxt,
variant_attrs: &Vec<syn::Attribute>,
enum_attrs: &Vec<syn::Attribute>,
) -> EventAttrs {
fn get_event_attrs_from(ctxt: &Ctxt, variant_attrs: &Vec<syn::Attribute>, enum_attrs: &Vec<syn::Attribute>) -> EventAttrs {
let mut event_attrs = EventAttrs {
input: None,
output: None,
@ -325,13 +291,7 @@ fn get_event_attrs_from(
enum_attrs
.iter()
.filter(|attr| {
attr.path
.segments
.iter()
.find(|s| s.ident == EVENT_ERR)
.is_some()
})
.filter(|attr| attr.path.segments.iter().find(|s| s.ident == EVENT_ERR).is_some())
.for_each(|attr| {
if let Ok(NameValue(named_value)) = attr.parse_meta() {
if let syn::Lit::Str(s) = named_value.lit {
@ -344,48 +304,34 @@ fn get_event_attrs_from(
}
});
let mut extract_event_attr =
|attr: &syn::Attribute, meta_item: &syn::NestedMeta| match &meta_item {
Meta(NameValue(name_value)) => {
if name_value.path == EVENT_INPUT {
if let syn::Lit::Str(s) = &name_value.lit {
let input_type = parse_lit_str(s)
.map_err(|_| {
ctxt.error_spanned_by(
s,
format!("failed to parse request deserializer {:?}", s.value()),
)
})
.unwrap();
event_attrs.input = Some(input_type);
}
let mut extract_event_attr = |attr: &syn::Attribute, meta_item: &syn::NestedMeta| match &meta_item {
Meta(NameValue(name_value)) => {
if name_value.path == EVENT_INPUT {
if let syn::Lit::Str(s) = &name_value.lit {
let input_type = parse_lit_str(s)
.map_err(|_| ctxt.error_spanned_by(s, format!("failed to parse request deserializer {:?}", s.value())))
.unwrap();
event_attrs.input = Some(input_type);
}
}
if name_value.path == EVENT_OUTPUT {
if let syn::Lit::Str(s) = &name_value.lit {
let output_type = parse_lit_str(s)
.map_err(|_| {
ctxt.error_spanned_by(
s,
format!(
"failed to parse response deserializer {:?}",
s.value()
),
)
})
.unwrap();
event_attrs.output = Some(output_type);
}
if name_value.path == EVENT_OUTPUT {
if let syn::Lit::Str(s) = &name_value.lit {
let output_type = parse_lit_str(s)
.map_err(|_| ctxt.error_spanned_by(s, format!("failed to parse response deserializer {:?}", s.value())))
.unwrap();
event_attrs.output = Some(output_type);
}
},
Meta(Path(word)) => {
if word == EVENT_IGNORE && attr.path == EVENT {
event_attrs.ignore = true;
}
},
Lit(s) => ctxt.error_spanned_by(s, "unexpected attribute"),
_ => ctxt.error_spanned_by(meta_item, "unexpected attribute"),
};
}
},
Meta(Path(word)) => {
if word == EVENT_IGNORE && attr.path == EVENT {
event_attrs.ignore = true;
}
},
Lit(s) => ctxt.error_spanned_by(s, "unexpected attribute"),
_ => ctxt.error_spanned_by(meta_item, "unexpected attribute"),
};
let attr_meta_items_info = variant_attrs
.iter()
@ -396,9 +342,7 @@ fn get_event_attrs_from(
.collect::<Vec<(&syn::Attribute, Vec<syn::NestedMeta>)>>();
for (attr, nested_metas) in attr_meta_items_info {
nested_metas
.iter()
.for_each(|meta_item| extract_event_attr(attr, meta_item))
nested_metas.iter().for_each(|meta_item| extract_event_attr(attr, meta_item))
}
// eprintln!("😁{:#?}", event_attrs);
@ -426,15 +370,9 @@ pub fn get_meta_items(cx: &Ctxt, attr: &syn::Attribute) -> Result<Vec<syn::Neste
}
}
fn parse_lit_into_expr_path(
cx: &Ctxt,
attr_name: Symbol,
lit: &syn::Lit,
) -> Result<syn::ExprPath, ()> {
fn parse_lit_into_expr_path(cx: &Ctxt, attr_name: Symbol, lit: &syn::Lit) -> Result<syn::ExprPath, ()> {
let string = get_lit_str(cx, attr_name, lit)?;
parse_lit_str(string).map_err(|_| {
cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()))
})
parse_lit_str(string).map_err(|_| cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value())))
}
fn get_lit_str<'a>(cx: &Ctxt, attr_name: Symbol, lit: &'a syn::Lit) -> Result<&'a syn::LitStr, ()> {
@ -443,10 +381,7 @@ fn get_lit_str<'a>(cx: &Ctxt, attr_name: Symbol, lit: &'a syn::Lit) -> Result<&'
} else {
cx.error_spanned_by(
lit,
format!(
"expected pb {} attribute to be a string: `{} = \"...\"`",
attr_name, attr_name
),
format!("expected pb {} attribute to be a string: `{} = \"...\"`", attr_name, attr_name),
);
Err(())
}
@ -455,12 +390,7 @@ fn get_lit_str<'a>(cx: &Ctxt, attr_name: Symbol, lit: &'a syn::Lit) -> Result<&'
fn parse_lit_into_ty(cx: &Ctxt, attr_name: Symbol, lit: &syn::Lit) -> Result<syn::Type, ()> {
let string = get_lit_str(cx, attr_name, lit)?;
parse_lit_str(string).map_err(|_| {
cx.error_spanned_by(
lit,
format!("failed to parse type: {} = {:?}", attr_name, string.value()),
)
})
parse_lit_str(string).map_err(|_| cx.error_spanned_by(lit, format!("failed to parse type: {} = {:?}", attr_name, string.value())))
}
pub fn parse_lit_str<T>(s: &syn::LitStr) -> parse::Result<T>
@ -477,10 +407,7 @@ fn spanned_tokens(s: &syn::LitStr) -> parse::Result<TokenStream> {
}
fn respan_token_stream(stream: TokenStream, span: Span) -> TokenStream {
stream
.into_iter()
.map(|token| respan_token_tree(token, span))
.collect()
stream.into_iter().map(|token| respan_token_tree(token, span)).collect()
}
fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
@ -499,10 +426,7 @@ fn default_pb_type(ctxt: &Ctxt, ident: &syn::Ident) -> syn::Type {
return pb_struct_ty;
}
}
ctxt.error_spanned_by(
ident,
format!("❌ Can't find {} protobuf struct", take_ident),
);
ctxt.error_spanned_by(ident, format!("❌ Can't find {} protobuf struct", take_ident));
panic!()
}

View File

@ -22,9 +22,7 @@ impl Ctxt {
.push(syn::Error::new_spanned(obj.into_token_stream(), msg));
}
pub fn syn_error(&self, err: syn::Error) {
self.errors.borrow_mut().as_mut().unwrap().push(err);
}
pub fn syn_error(&self, err: syn::Error) { self.errors.borrow_mut().as_mut().unwrap().push(err); }
pub fn check(self) -> Result<(), Vec<syn::Error>> {
let errors = self.errors.borrow_mut().take().unwrap();

View File

@ -58,10 +58,4 @@ table! {
}
}
allow_tables_to_appear_in_same_query!(
app_table,
doc_table,
user_table,
view_table,
workspace_table,
);
allow_tables_to_appear_in_same_query!(app_table, doc_table, user_table, view_table, workspace_table,);

View File

@ -1,9 +1,7 @@
use proc_macro2::TokenStream;
// #[proc_macro_derive(DartEvent, attributes(event_ty))]
pub fn expand_enum_derive(_input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
Ok(TokenStream::default())
}
pub fn expand_enum_derive(_input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> { Ok(TokenStream::default()) }
// use flowy_ast::{ASTContainer, Ctxt};
// use proc_macro2::TokenStream;

View File

@ -69,8 +69,7 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
| "UserProfile"
| "UpdateUserRequest"
| "UpdateUserParams"
| "UserError"
=> TypeCategory::Protobuf,
| "UserError" => TypeCategory::Protobuf,
"ViewType"
| "WorkspaceEvent"
| "ErrorCode"
@ -80,8 +79,7 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
| "FFIStatusCode"
| "UserStatus"
| "UserEvent"
| "UserObservable"
=> TypeCategory::Enum,
| "UserObservable" => TypeCategory::Enum,
"Option" => TypeCategory::Opt,
_ => TypeCategory::Primitive,

View File

@ -16,25 +16,19 @@ mod proto_buf;
#[proc_macro_derive(ProtoBuf, attributes(pb))]
pub fn derive_proto_buf(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
proto_buf::expand_derive(&input)
.unwrap_or_else(to_compile_errors)
.into()
proto_buf::expand_derive(&input).unwrap_or_else(to_compile_errors).into()
}
#[proc_macro_derive(ProtoBuf_Enum, attributes(pb))]
pub fn derive_proto_buf_enum(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
proto_buf::expand_enum_derive(&input)
.unwrap_or_else(to_compile_errors)
.into()
proto_buf::expand_enum_derive(&input).unwrap_or_else(to_compile_errors).into()
}
#[proc_macro_derive(Flowy_Event, attributes(event, event_err))]
pub fn derive_dart_event(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
dart_event::expand_enum_derive(&input)
.unwrap_or_else(to_compile_errors)
.into()
dart_event::expand_enum_derive(&input).unwrap_or_else(to_compile_errors).into()
}
fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {

View File

@ -6,20 +6,16 @@ pub fn make_de_token_steam(ctxt: &Ctxt, ast: &ASTContainer) -> Option<TokenStrea
let pb_ty = ast.attrs.pb_struct_type()?;
let struct_ident = &ast.ident;
let build_take_fields = ast
.data
.all_fields()
.filter(|f| !f.attrs.skip_deserializing())
.flat_map(|field| {
if let Some(func) = field.attrs.deserialize_with() {
let member = &field.member;
Some(quote! { o.#member=#struct_ident::#func(pb); })
} else if field.attrs.is_one_of() {
token_stream_for_one_of(ctxt, field)
} else {
token_stream_for_field(ctxt, &field.member, &field.ty, false)
}
});
let build_take_fields = ast.data.all_fields().filter(|f| !f.attrs.skip_deserializing()).flat_map(|field| {
if let Some(func) = field.attrs.deserialize_with() {
let member = &field.member;
Some(quote! { o.#member=#struct_ident::#func(pb); })
} else if field.attrs.is_one_of() {
token_stream_for_one_of(ctxt, field)
} else {
token_stream_for_field(ctxt, &field.member, &field.ty, false)
}
});
let de_token_stream: TokenStream = quote! {
impl std::convert::TryFrom<bytes::Bytes> for #struct_ident {
@ -102,12 +98,7 @@ fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option<TokenStream>
}
}
fn token_stream_for_field(
ctxt: &Ctxt,
member: &syn::Member,
ty: &syn::Type,
is_option: bool,
) -> Option<TokenStream> {
fn token_stream_for_field(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type, is_option: bool) -> Option<TokenStream> {
let ident = get_member_ident(ctxt, member)?;
let ty_info = parse_ty(ctxt, ty)?;
match ident_category(ty_info.ident) {
@ -142,8 +133,7 @@ fn token_stream_for_field(
})
},
TypeCategory::Str => {
let take_ident =
syn::Ident::new(&format!("take_{}", ident.to_string()), Span::call_site());
let take_ident = syn::Ident::new(&format!("take_{}", ident.to_string()), Span::call_site());
if is_option {
Some(quote! {
if pb.#member.is_empty() {
@ -158,9 +148,7 @@ fn token_stream_for_field(
})
}
},
TypeCategory::Opt => {
token_stream_for_field(ctxt, member, ty_info.bracket_ty_info.unwrap().ty, true)
},
TypeCategory::Opt => token_stream_for_field(ctxt, member, ty_info.bracket_ty_info.unwrap().ty, true),
TypeCategory::Primitive | TypeCategory::Bytes => {
// eprintln!("😄 #{:?}", &field.name().unwrap());
if is_option {
@ -172,11 +160,7 @@ fn token_stream_for_field(
}
}
fn token_stream_for_vec(
ctxt: &Ctxt,
member: &syn::Member,
bracketed_type: &TyInfo,
) -> Option<TokenStream> {
fn token_stream_for_vec(ctxt: &Ctxt, member: &syn::Member, bracketed_type: &TyInfo) -> Option<TokenStream> {
let ident = get_member_ident(ctxt, member)?;
match ident_category(bracketed_type.ident) {
@ -208,11 +192,7 @@ fn token_stream_for_vec(
}
}
fn token_stream_for_map(
ctxt: &Ctxt,
member: &syn::Member,
bracketed_type: &TyInfo,
) -> Option<TokenStream> {
fn token_stream_for_map(ctxt: &Ctxt, member: &syn::Member, bracketed_type: &TyInfo) -> Option<TokenStream> {
let ident = get_member_ident(ctxt, member)?;
let take_ident = format_ident!("take_{}", ident.to_string());

View File

@ -3,11 +3,7 @@ mod enum_serde;
mod serialize;
mod util;
use crate::proto_buf::{
deserialize::make_de_token_steam,
enum_serde::make_enum_token_stream,
serialize::make_se_token_stream,
};
use crate::proto_buf::{deserialize::make_de_token_steam, enum_serde::make_enum_token_stream, serialize::make_se_token_stream};
use flowy_ast::*;
use proc_macro2::TokenStream;

View File

@ -76,18 +76,11 @@ fn token_stream_for_one_of(ctxt: &Ctxt, field: &ASTField) -> Option<TokenStream>
}
}
fn gen_token_stream(
ctxt: &Ctxt,
member: &syn::Member,
ty: &syn::Type,
is_option: bool,
) -> Option<TokenStream> {
fn gen_token_stream(ctxt: &Ctxt, member: &syn::Member, ty: &syn::Type, is_option: bool) -> Option<TokenStream> {
let ty_info = parse_ty(ctxt, ty)?;
match ident_category(ty_info.ident) {
TypeCategory::Array => token_stream_for_vec(ctxt, &member, &ty_info.ty),
TypeCategory::Map => {
token_stream_for_map(ctxt, &member, &ty_info.bracket_ty_info.unwrap().ty)
},
TypeCategory::Map => token_stream_for_map(ctxt, &member, &ty_info.bracket_ty_info.unwrap().ty),
TypeCategory::Str => {
if is_option {
Some(quote! {
@ -100,12 +93,8 @@ fn gen_token_stream(
Some(quote! { pb.#member = self.#member.clone(); })
}
},
TypeCategory::Protobuf => Some(
quote! { pb.#member = ::protobuf::SingularPtrField::some(self.#member.try_into().unwrap()); },
),
TypeCategory::Opt => {
gen_token_stream(ctxt, member, ty_info.bracket_ty_info.unwrap().ty, true)
},
TypeCategory::Protobuf => Some(quote! { pb.#member = ::protobuf::SingularPtrField::some(self.#member.try_into().unwrap()); }),
TypeCategory::Opt => gen_token_stream(ctxt, member, ty_info.bracket_ty_info.unwrap().ty, true),
TypeCategory::Enum => {
// let pb_enum_ident = format_ident!("{}", ty_info.ident.to_string());
// Some(quote! {

View File

@ -17,9 +17,6 @@ pub(crate) fn get_member_ident<'a>(ctxt: &Ctxt, member: &'a syn::Member) -> Opti
pub fn assert_bracket_ty_is_some(ctxt: &Ctxt, ty_info: &TyInfo) {
if ty_info.bracket_ty_info.is_none() {
ctxt.error_spanned_by(
ty_info.ty,
format!("Invalid bracketed type when gen de token steam"),
);
ctxt.error_spanned_by(ty_info.ty, format!("Invalid bracketed type when gen de token steam"));
}
}

View File

@ -37,9 +37,7 @@ where
Payload::None => ready(Err(unexpected_none_payload(req))),
Payload::Bytes(bytes) => match T::parse_from_bytes(bytes.clone()) {
Ok(data) => ready(Ok(Data(data))),
Err(e) => ready(Err(
InternalError::DeserializeFromBytes(format!("{}", e)).into()
)),
Err(e) => ready(Err(InternalError::DeserializeFromBytes(format!("{}", e)).into())),
},
}
}
@ -78,9 +76,7 @@ where
T: FromBytes,
{
match payload {
Payload::None => {
Err(InternalError::UnexpectedNone(format!("Parse fail, expected payload")).into())
},
Payload::None => Err(InternalError::UnexpectedNone(format!("Parse fail, expected payload")).into()),
Payload::Bytes(bytes) => {
let data = T::parse_from_bytes(bytes.clone())?;
Ok(Data(data))

View File

@ -16,13 +16,5 @@ pub mod macros;
pub use errors::Error;
pub mod prelude {
pub use crate::{
byte_trait::*,
data::*,
dispatch::*,
errors::*,
module::*,
request::*,
response::*,
};
pub use crate::{byte_trait::*, data::*, dispatch::*, errors::*, module::*, request::*, response::*};
}

View File

@ -10,19 +10,13 @@ pub struct ModuleDataMap {
impl ModuleDataMap {
#[inline]
pub fn new() -> ModuleDataMap {
ModuleDataMap {
map: HashMap::default(),
}
}
pub fn new() -> ModuleDataMap { ModuleDataMap { map: HashMap::default() } }
pub fn insert<T>(&mut self, val: T) -> Option<T>
where
T: 'static + Send + Sync,
{
self.map
.insert(TypeId::of::<T>(), Box::new(val))
.and_then(downcast_owned)
self.map.insert(TypeId::of::<T>(), Box::new(val)).and_then(downcast_owned)
}
pub fn remove<T>(&mut self) -> Option<T>
@ -36,18 +30,14 @@ impl ModuleDataMap {
where
T: 'static + Send + Sync,
{
self.map
.get(&TypeId::of::<T>())
.and_then(|boxed| boxed.downcast_ref())
self.map.get(&TypeId::of::<T>()).and_then(|boxed| boxed.downcast_ref())
}
pub fn get_mut<T>(&mut self) -> Option<&mut T>
where
T: 'static + Send + Sync,
{
self.map
.get_mut(&TypeId::of::<T>())
.and_then(|boxed| boxed.downcast_mut())
self.map.get_mut(&TypeId::of::<T>()).and_then(|boxed| boxed.downcast_mut())
}
pub fn contains<T>(&self) -> bool
@ -60,6 +50,4 @@ impl ModuleDataMap {
pub fn extend(&mut self, other: ModuleDataMap) { self.map.extend(other.map); }
}
fn downcast_owned<T: 'static + Send + Sync>(boxed: Box<dyn Any + Send + Sync>) -> Option<T> {
boxed.downcast().ok().map(|boxed| *boxed)
}
fn downcast_owned<T: 'static + Send + Sync>(boxed: Box<dyn Any + Send + Sync>) -> Option<T> { boxed.downcast().ok().map(|boxed| *boxed) }

View File

@ -51,10 +51,7 @@ where
if let Some(data) = req.module_data::<Unit<T>>() {
ready(Ok(data.clone()))
} else {
let msg = format!(
"Failed to get the module data of type: {}",
type_name::<T>()
);
let msg = format!("Failed to get the module data of type: {}", type_name::<T>());
log::error!("{}", msg,);
ready(Err(InternalError::Other(msg).into()))
}

View File

@ -13,9 +13,7 @@ pub trait Responder {
macro_rules! impl_responder {
($res: ty) => {
impl Responder for $res {
fn respond_to(self, _: &EventRequest) -> EventResponse {
ResponseBuilder::Ok().data(self).build()
}
fn respond_to(self, _: &EventRequest) -> EventResponse { ResponseBuilder::Ok().data(self).build() }
}
};
}

View File

@ -44,11 +44,8 @@ where
fn new_service(&self, cfg: Cfg) -> Self::Future { self.0.new_service(cfg) }
}
pub type BoxService<Req, Res, Err> = Box<
dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<'static, Result<Res, Err>>>
+ Sync
+ Send,
>;
pub type BoxService<Req, Res, Err> =
Box<dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<'static, Result<Res, Err>>> + Sync + Send>;
// #[allow(dead_code)]
// pub fn service<S, Req>(service: S) -> BoxService<Req, S::Response, S::Error>
@ -112,9 +109,6 @@ where
fn new_service(&self, cfg: Cfg) -> Self::Future {
let f = self.0.new_service(cfg);
Box::pin(async {
f.await
.map(|s| Box::new(ServiceWrapper::new(s)) as Self::Service)
})
Box::pin(async { f.await.map(|s| Box::new(ServiceWrapper::new(s)) as Self::Service) })
}
}

View File

@ -41,9 +41,7 @@ pub struct ServiceResponse {
}
impl ServiceResponse {
pub fn new(request: EventRequest, response: EventResponse) -> Self {
ServiceResponse { request, response }
}
pub fn new(request: EventRequest, response: EventResponse) -> Self { ServiceResponse { request, response } }
pub fn into_parts(self) -> (EventRequest, EventResponse) { (self.request, self.response) }
}

View File

@ -44,10 +44,7 @@ impl FlowySystem {
let system = Self { sys_cmd_tx };
FlowySystem::set_current(system);
let runner = SystemRunner {
rt: runtime,
stop_rx,
};
let runner = SystemRunner { rt: runtime, stop_rx };
runner
}
@ -112,10 +109,7 @@ impl SystemRunner {
match rt.block_on(stop_rx) {
Ok(code) => {
if code != 0 {
Err(io::Error::new(
io::ErrorKind::Other,
format!("Non-zero exit code: {}", code),
))
Err(io::Error::new(io::ErrorKind::Other, format!("Non-zero exit code: {}", code)))
} else {
Ok(())
}

View File

@ -10,18 +10,10 @@ pub(crate) fn tokio_default_runtime() -> io::Result<tokio::runtime::Runtime> {
.enable_io()
.enable_time()
.on_thread_start(move || {
log::trace!(
"{:?} thread started: thread_id= {}",
thread::current(),
thread_id::get()
);
log::trace!("{:?} thread started: thread_id= {}", thread::current(), thread_id::get());
})
.on_thread_stop(move || {
log::trace!(
"{:?} thread stopping: thread_id= {}",
thread::current(),
thread_id::get(),
);
log::trace!("{:?} thread stopping: thread_id= {}", thread::current(), thread_id::get(),);
})
.build()
}

View File

@ -1,10 +1,10 @@
#[rustfmt::skip]
use flowy_dispatch::prelude::*;
use std::sync::Once;
#[allow(dead_code)]
pub fn setup_env() {
static INIT: Once = Once::new();
std::env::);
INIT.call_once(|| env_logger::init());
}

View File

@ -1,4 +1,2 @@
mod model;
pub use model::*;

View File

@ -1,13 +1,13 @@
// Auto-generated, do not edit
// Auto-generated, do not edit
mod observable;
pub use observable::*;
mod observable;
pub use observable::*;
mod errors;
pub use errors::*;
mod errors;
pub use errors::*;
mod event;
pub use event::*;
mod event;
pub use event::*;
mod doc;
pub use doc::*;
mod doc;
pub use doc::*;

View File

@ -32,7 +32,7 @@ impl DocController {
Ok(())
}
#[tracing::instrument(level = "debug", skip(self, conn), err)]
#[tracing::instrument(level = "debug", skip(self, conn, params), err)]
pub fn update(&self, params: UpdateDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
let changeset = DocTableChangeset::new(params.clone());
let _ = self.sql.update_doc_table(changeset, &*conn)?;
@ -58,7 +58,7 @@ impl DocController {
}
impl DocController {
#[tracing::instrument(level = "debug", skip(self), err)]
#[tracing::instrument(level = "debug", skip(self, params), err)]
fn update_doc_on_server(&self, params: UpdateDocParams) -> Result<(), DocError> {
let token = self.user.token()?;
let server = self.server.clone();

View File

@ -1,4 +1,2 @@
mod model;
pub use model::*;

View File

@ -1,4 +1,4 @@
// Auto-generated, do not edit
// Auto-generated, do not edit
mod kv;
pub use kv::*;
mod kv;
pub use kv::*;

View File

@ -4,7 +4,7 @@ use std::{fmt, io::Write};
use tracing::{Event, Id, Subscriber};
use tracing_bunyan_formatter::JsonStorage;
use tracing_core::{metadata::Level, span::Attributes};
use tracing_log::AsLog;
use tracing_subscriber::{fmt::MakeWriter, layer::Context, registry::SpanRef, Layer};
const LEVEL: &str = "level";
const TIME: &str = "time";

View File

@ -5,9 +5,9 @@ use std::path::Path;
use tracing::subscriber::set_global_default;
use crate::layer::*;
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
use tracing_bunyan_formatter::JsonStorageLayer;
use tracing_log::LogTracer;
use tracing_subscriber::{fmt::format::FmtSpan, layer::SubscriberExt, EnvFilter};
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
pub struct Builder {
name: String,

View File

@ -16,10 +16,7 @@ impl FlowyResponse {
pub fn success() -> Self { Self::new(Bytes::new(), None) }
pub fn data<T: TryInto<Bytes, Error = protobuf::ProtobufError>>(
mut self,
data: T,
) -> Result<Self, ServerError> {
pub fn data<T: TryInto<Bytes, Error = protobuf::ProtobufError>>(mut self, data: T) -> Result<Self, ServerError> {
let bytes: Bytes = data.try_into()?;
self.data = bytes;
Ok(self)

View File

@ -50,7 +50,7 @@
// return
// Err(de::Error::duplicate_field("data")); }
// data = match
// MapAccess::next_value::<DeserializeWith<T>>(&mut map) {
// MapAccess::next_value::<DeserializeWith<T>>(&mut map) {
// Ok(wrapper) => wrapper.value, Err(err) =>
// return Err(err), };
// },
@ -59,7 +59,7 @@
// }
// let msg = msg.ok_or_else(||
// de::Error::missing_field("msg"))?; let code =
// code.ok_or_else(|| de::Error::missing_field("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"];

View File

@ -1,4 +1,2 @@
mod model;
pub use model::*;

View File

@ -1,4 +1,4 @@
// Auto-generated, do not edit
// Auto-generated, do not edit
mod subject;
pub use subject::*;
mod subject;
pub use subject::*;

View File

@ -8,11 +8,6 @@ impl DeleteExt for DefaultDelete {
fn ext_name(&self) -> &str { "DefaultDelete" }
fn apply(&self, _delta: &Delta, interval: Interval) -> Option<Delta> {
Some(
DeltaBuilder::new()
.retain(interval.start)
.delete(interval.size())
.build(),
)
Some(DeltaBuilder::new().retain(interval.start).delete(interval.size()).build())
}
}

View File

@ -1,6 +1,6 @@
use crate::{
client::{extensions::DeleteExt, util::is_newline},
core::{Attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, Interval, NEW_LINE},
core::{plain_attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, Interval, NEW_LINE},
};
pub struct PreserveLineFormatOnMerge {}
@ -22,10 +22,7 @@ impl DeleteExt for PreserveLineFormatOnMerge {
}
iter.seek::<CharMetric>(interval.size() - 1);
let mut new_delta = DeltaBuilder::new()
.retain(interval.start)
.delete(interval.size())
.build();
let mut new_delta = DeltaBuilder::new().retain(interval.start).delete(interval.size()).build();
while iter.has_next() {
match iter.next() {
@ -34,7 +31,7 @@ impl DeleteExt for PreserveLineFormatOnMerge {
//
match op.get_data().find(NEW_LINE) {
None => {
new_delta.retain(op.len(), Attributes::empty());
new_delta.retain(op.len(), plain_attributes());
continue;
},
Some(line_break) => {
@ -45,7 +42,7 @@ impl DeleteExt for PreserveLineFormatOnMerge {
attributes.extend(newline_op.get_attributes());
}
new_delta.retain(line_break, Attributes::empty());
new_delta.retain(line_break, plain_attributes());
new_delta.retain(1, attributes);
break;
},

View File

@ -1,6 +1,6 @@
use crate::{
client::util::find_newline,
core::{Attribute, AttributeScope, Attributes, Delta, Operation},
core::{plain_attributes, Attribute, AttributeScope, Delta, Operation},
};
pub(crate) fn line_break(op: &Operation, attribute: &Attribute, scope: AttributeScope) -> Delta {
@ -13,10 +13,10 @@ pub(crate) fn line_break(op: &Operation, attribute: &Attribute, scope: Attribute
match scope {
AttributeScope::Inline => {
new_delta.retain(line_break - start, attribute.clone().into());
new_delta.retain(1, Attributes::empty());
new_delta.retain(1, plain_attributes());
},
AttributeScope::Block => {
new_delta.retain(line_break - start, Attributes::empty());
new_delta.retain(line_break - start, plain_attributes());
new_delta.retain(1, attribute.clone().into());
},
_ => {
@ -31,7 +31,7 @@ pub(crate) fn line_break(op: &Operation, attribute: &Attribute, scope: Attribute
if start < end {
match scope {
AttributeScope::Inline => new_delta.retain(end - start, attribute.clone().into()),
AttributeScope::Block => new_delta.retain(end - start, Attributes::empty()),
AttributeScope::Block => new_delta.retain(end - start, plain_attributes()),
_ => log::error!("Unsupported parser line break for {:?}", scope),
}
}

View File

@ -3,7 +3,7 @@ use crate::{
extensions::{format::helper::line_break, FormatExt},
util::find_newline,
},
core::{Attribute, AttributeScope, Attributes, Delta, DeltaBuilder, DeltaIter, Interval},
core::{plain_attributes, Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval},
};
pub struct ResolveBlockFormat {}
@ -22,7 +22,7 @@ impl FormatExt for ResolveBlockFormat {
while start < end && iter.has_next() {
let next_op = iter.next_op_with_len(end - start).unwrap();
match find_newline(next_op.get_data()) {
None => new_delta.retain(next_op.len(), Attributes::empty()),
None => new_delta.retain(next_op.len(), plain_attributes()),
Some(_) => {
let tmp_delta = line_break(&next_op, attribute, AttributeScope::Block);
new_delta.extend(tmp_delta);
@ -33,14 +33,12 @@ impl FormatExt for ResolveBlockFormat {
}
while iter.has_next() {
let op = iter
.next_op()
.expect("Unexpected None, iter.has_next() must return op");
let op = iter.next_op().expect("Unexpected None, iter.has_next() must return op");
match find_newline(op.get_data()) {
None => new_delta.retain(op.len(), Attributes::empty()),
None => new_delta.retain(op.len(), plain_attributes()),
Some(line_break) => {
new_delta.retain(line_break, Attributes::empty());
new_delta.retain(line_break, plain_attributes());
new_delta.retain(1, attribute.clone().into());
break;
},

View File

@ -31,7 +31,7 @@ impl InsertExt for AutoFormatExt {
});
let next_attributes = match iter.next_op() {
None => Attributes::empty(),
None => plain_attributes(),
Some(op) => op.get_attributes(),
};
@ -50,7 +50,7 @@ impl InsertExt for AutoFormatExt {
}
}
use crate::core::{AttributeBuilder, Attributes, DeltaBuilder};
use crate::core::{plain_attributes, Attribute, Attributes, DeltaBuilder};
use bytecount::num_chars;
use std::cmp::min;
use url::Url;
@ -62,7 +62,7 @@ pub enum AutoFormatter {
impl AutoFormatter {
pub fn to_attributes(&self) -> Attributes {
match self {
AutoFormatter::Url(url) => AttributeBuilder::new().link(url.as_str(), true).build(),
AutoFormatter::Url(url) => Attribute::Link(url.as_str()).into(),
}
}

View File

@ -18,28 +18,12 @@ pub struct InsertEmbedsExt {}
impl InsertExt for InsertEmbedsExt {
fn ext_name(&self) -> &str { "InsertEmbedsExt" }
fn apply(
&self,
_delta: &Delta,
_replace_len: usize,
_text: &str,
_index: usize,
) -> Option<Delta> {
None
}
fn apply(&self, _delta: &Delta, _replace_len: usize, _text: &str, _index: usize) -> Option<Delta> { None }
}
pub struct ForceNewlineForInsertsAroundEmbedExt {}
impl InsertExt for ForceNewlineForInsertsAroundEmbedExt {
fn ext_name(&self) -> &str { "ForceNewlineForInsertsAroundEmbedExt" }
fn apply(
&self,
_delta: &Delta,
_replace_len: usize,
_text: &str,
_index: usize,
) -> Option<Delta> {
None
}
fn apply(&self, _delta: &Delta, _replace_len: usize, _text: &str, _index: usize) -> Option<Delta> { None }
}

View File

@ -1,14 +1,6 @@
use crate::{
client::{extensions::InsertExt, util::is_newline},
core::{
attributes_except_header,
AttributeKey,
Attributes,
Delta,
DeltaBuilder,
DeltaIter,
NEW_LINE,
},
core::{attributes_except_header, plain_attributes, Attribute, AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, NEW_LINE},
};
pub struct PreserveBlockFormatOnInsert {}
@ -32,14 +24,14 @@ impl InsertExt for PreserveBlockFormatOnInsert {
let mut reset_attribute = Attributes::new();
if newline_attributes.contains_key(&AttributeKey::Header) {
reset_attribute.add(AttributeKey::Header.value(""));
reset_attribute.add(Attribute::Header(1));
}
let lines: Vec<_> = text.split(NEW_LINE).collect();
let mut new_delta = DeltaBuilder::new().retain(index + replace_len).build();
lines.iter().enumerate().for_each(|(i, line)| {
if !line.is_empty() {
new_delta.insert(line, Attributes::empty());
new_delta.insert(line, plain_attributes());
}
if i == 0 {
@ -51,9 +43,9 @@ impl InsertExt for PreserveBlockFormatOnInsert {
}
});
if !reset_attribute.is_empty() {
new_delta.retain(offset, Attributes::empty());
new_delta.retain(offset, plain_attributes());
let len = newline_op.get_data().find(NEW_LINE).unwrap();
new_delta.retain(len, Attributes::empty());
new_delta.retain(len, plain_attributes());
new_delta.retain(1, reset_attribute.clone());
}

View File

@ -3,7 +3,7 @@ use crate::{
extensions::InsertExt,
util::{contain_newline, is_newline},
},
core::{AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, OpNewline, NEW_LINE},
core::{plain_attributes, AttributeKey, Delta, DeltaBuilder, DeltaIter, OpNewline, NEW_LINE},
};
pub struct PreserveInlineFormat {}
@ -33,10 +33,10 @@ impl InsertExt for PreserveInlineFormat {
let next = iter.next_op();
match &next {
None => attributes = Attributes::empty(),
None => attributes = plain_attributes(),
Some(next) => {
if OpNewline::parse(&next).is_equal() {
attributes = Attributes::empty();
attributes = plain_attributes();
}
},
}
@ -72,11 +72,11 @@ impl InsertExt for PreserveLineFormatOnSplit {
}
let mut new_delta = Delta::new();
new_delta.retain(index + replace_len, Attributes::empty());
new_delta.retain(index + replace_len, plain_attributes());
if newline_status.is_contain() {
debug_assert!(next.has_attribute() == false);
new_delta.insert(NEW_LINE, Attributes::empty());
new_delta.insert(NEW_LINE, plain_attributes());
return Some(new_delta);
}

View File

@ -21,7 +21,7 @@ impl InsertExt for ResetLineFormatOnNewLine {
let mut reset_attribute = Attributes::new();
if next_op.get_attributes().contains_key(&AttributeKey::Header) {
reset_attribute.add(AttributeKey::Header.value(""));
reset_attribute.mark_as_removed(&AttributeKey::Header);
}
let len = index + replace_len;

View File

@ -22,12 +22,7 @@ pub struct UndoResult {
}
impl UndoResult {
pub fn fail() -> Self {
UndoResult {
success: false,
len: 0,
}
}
pub fn fail() -> Self { UndoResult { success: false, len: 0 } }
pub fn success(len: usize) -> Self { UndoResult { success: true, len } }
}

View File

@ -21,12 +21,7 @@ impl View {
}
}
pub(crate) fn insert(
&self,
delta: &Delta,
text: &str,
interval: Interval,
) -> Result<Delta, OTError> {
pub(crate) fn insert(&self, delta: &Delta, text: &str, interval: Interval) -> Result<Delta, OTError> {
let mut new_delta = None;
for ext in &self.insert_exts {
if let Some(delta) = ext.apply(delta, interval.size(), text, interval.start) {
@ -58,12 +53,7 @@ impl View {
}
}
pub(crate) fn format(
&self,
delta: &Delta,
attribute: Attribute,
interval: Interval,
) -> Result<Delta, OTError> {
pub(crate) fn format(&self, delta: &Delta, attribute: Attribute, interval: Interval) -> Result<Delta, OTError> {
let mut new_delta = None;
for ext in &self.format_exts {
if let Some(delta) = ext.apply(delta, interval, &attribute) {
@ -102,9 +92,4 @@ fn construct_format_exts() -> Vec<FormatExtension> {
]
}
fn construct_delete_exts() -> Vec<DeleteExtension> {
vec![
Box::new(PreserveLineFormatOnMerge {}),
Box::new(DefaultDelete {}),
]
}
fn construct_delete_exts() -> Vec<DeleteExtension> { vec![Box::new(PreserveLineFormatOnMerge {}), Box::new(DefaultDelete {})] }

View File

@ -1,3 +1,4 @@
#![allow(non_snake_case)]
use crate::core::{Attributes, REMOVE_FLAG};
use derive_more::Display;
use lazy_static::lazy_static;
@ -31,8 +32,7 @@ lazy_static! {
AttributeKey::Size,
AttributeKey::Background,
]);
static ref INGORE_KEYS: HashSet<AttributeKey> =
HashSet::from_iter(vec![AttributeKey::Width, AttributeKey::Height,]);
static ref INGORE_KEYS: HashSet<AttributeKey> = HashSet::from_iter(vec![AttributeKey::Width, AttributeKey::Height,]);
}
#[derive(Debug, PartialEq, Eq, Clone)]
@ -43,6 +43,51 @@ pub enum AttributeScope {
Ignore,
}
macro_rules! inline_attribute {
(
$key: ident,
$value: ty
) => {
pub fn $key(value: $value) -> Self {
Self {
key: AttributeKey::$key,
value: value.into(),
scope: AttributeScope::Inline,
}
}
};
}
macro_rules! block_attribute {
(
$key: ident,
$value: ident
) => {
pub fn $key(value: $value) -> Self {
Self {
key: AttributeKey::$key,
value: value.into(),
scope: AttributeScope::Block,
}
}
};
}
macro_rules! ignore_attribute {
(
$key: ident,
$value: ident
) => {
pub fn $key(value: $value) -> Self {
Self {
key: AttributeKey::$key,
value: value.into(),
scope: AttributeScope::Ignore,
}
}
};
}
#[derive(Debug, Clone)]
pub struct Attribute {
pub key: AttributeKey,
@ -50,6 +95,36 @@ pub struct Attribute {
pub scope: AttributeScope,
}
impl Attribute {
inline_attribute!(Bold, bool);
inline_attribute!(Italic, bool);
inline_attribute!(Underline, bool);
inline_attribute!(StrikeThrough, bool);
inline_attribute!(Link, &str);
inline_attribute!(Color, String);
inline_attribute!(Font, usize);
inline_attribute!(Size, usize);
inline_attribute!(Background, String);
block_attribute!(Header, usize);
block_attribute!(LeftAlignment, usize);
block_attribute!(CenterAlignment, usize);
block_attribute!(RightAlignment, usize);
block_attribute!(JustifyAlignment, bool);
block_attribute!(Indent, String);
block_attribute!(Align, String);
block_attribute!(CodeBlock, String);
block_attribute!(List, String);
block_attribute!(Bullet, bool);
block_attribute!(Ordered, bool);
block_attribute!(Checked, bool);
block_attribute!(UnChecked, bool);
block_attribute!(QuoteBlock, bool);
ignore_attribute!(Width, usize);
ignore_attribute!(Height, usize);
}
impl fmt::Display for Attribute {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let s = format!("{:?}:{} {:?}", self.key, self.value.as_ref(), self.scope);
@ -120,91 +195,6 @@ pub enum AttributeKey {
UnChecked,
}
impl AttributeKey {
pub fn remove(&self) -> Attribute { self.value(REMOVE_FLAG) }
pub fn value<T: Into<AttributeValue>>(&self, value: T) -> Attribute {
let key = self.clone();
let value: AttributeValue = value.into();
debug_assert_eq!(self.check_value(&value), true);
if INLINE_KEYS.contains(self) {
return Attribute {
key,
value,
scope: AttributeScope::Inline,
};
}
if BLOCK_KEYS.contains(self) {
return Attribute {
key,
value,
scope: AttributeScope::Block,
};
}
Attribute {
key,
value,
scope: AttributeScope::Ignore,
}
}
fn check_value(&self, value: &AttributeValue) -> bool {
if value.0.is_empty() {
return true;
}
match self {
AttributeKey::Bold
| AttributeKey::Italic
| AttributeKey::Underline
| AttributeKey::StrikeThrough
| AttributeKey::Indent
| AttributeKey::Align
| AttributeKey::CodeBlock
| AttributeKey::List
| AttributeKey::QuoteBlock
| AttributeKey::JustifyAlignment
| AttributeKey::Bullet
| AttributeKey::Ordered
| AttributeKey::Checked
| AttributeKey::UnChecked => {
if let Err(e) = value.0.parse::<bool>() {
log::error!(
"Parser failed: {:?}. expected bool, but receive {}",
e,
value.0
);
return false;
}
},
AttributeKey::Link | AttributeKey::Color | AttributeKey::Background => {},
AttributeKey::Header
| AttributeKey::Width
| AttributeKey::Height
| AttributeKey::Font
| AttributeKey::Size
| AttributeKey::LeftAlignment
| AttributeKey::CenterAlignment
| AttributeKey::RightAlignment => {
if let Err(e) = value.0.parse::<usize>() {
log::error!(
"Parser failed: {:?}. expected usize, but receive {}",
e,
value.0
);
return false;
}
},
}
true
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AttributeValue(pub(crate) String);
@ -213,13 +203,33 @@ impl AsRef<str> for AttributeValue {
}
impl std::convert::From<&usize> for AttributeValue {
fn from(val: &usize) -> Self { AttributeValue(format!("{}", val)) }
fn from(val: &usize) -> Self {
if *val > (0 as usize) {
AttributeValue(format!("{}", val))
} else {
AttributeValue(format!(""))
}
}
}
impl std::convert::From<usize> for AttributeValue {
fn from(val: usize) -> Self {
if val > (0 as usize) {
AttributeValue(format!("{}", val))
} else {
AttributeValue(format!(""))
}
}
}
impl std::convert::From<&str> for AttributeValue {
fn from(val: &str) -> Self { AttributeValue(val.to_owned()) }
}
impl std::convert::From<String> for AttributeValue {
fn from(val: String) -> Self { AttributeValue(val) }
}
impl std::convert::From<bool> for AttributeValue {
fn from(val: bool) -> Self {
let val = match val {

View File

@ -4,36 +4,34 @@ use std::{collections::HashMap, fmt};
pub const REMOVE_FLAG: &'static str = "";
pub(crate) fn should_remove(val: &AttributeValue) -> bool { val.0 == REMOVE_FLAG }
#[derive(Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct Attributes {
#[serde(skip_serializing_if = "HashMap::is_empty")]
#[serde(flatten)]
pub(crate) inner: HashMap<AttributeKey, AttributeValue>,
}
impl fmt::Display for Attributes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{:?}", self.inner))
impl std::default::Default for Attributes {
fn default() -> Self {
Self {
inner: HashMap::with_capacity(0),
}
}
}
impl Attributes {
pub fn new() -> Self {
Attributes {
inner: HashMap::new(),
}
}
impl fmt::Display for Attributes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_fmt(format_args!("{:?}", self.inner)) }
}
pub fn empty() -> Self { Self::default() }
pub fn plain_attributes() -> Attributes { Attributes::default() }
impl Attributes {
pub fn new() -> Self { Attributes { inner: HashMap::new() } }
pub fn is_empty(&self) -> bool { self.inner.is_empty() }
pub fn add(&mut self, attribute: Attribute) {
let Attribute {
key,
value,
scope: _,
} = attribute;
let Attribute { key, value, scope: _ } = attribute;
self.inner.insert(key, value);
}
@ -45,9 +43,7 @@ impl Attributes {
pub fn mark_all_as_removed_except(&mut self, attribute: Option<AttributeKey>) {
match attribute {
None => {
self.inner
.iter_mut()
.for_each(|(_k, v)| v.0 = REMOVE_FLAG.into());
self.inner.iter_mut().for_each(|(_k, v)| v.0 = REMOVE_FLAG.into());
},
Some(attribute) => {
self.inner.iter_mut().for_each(|(k, v)| {
@ -153,24 +149,21 @@ pub fn transform_operation(left: &Option<Operation>, right: &Option<Operation>)
let left = attr_l.unwrap();
let right = attr_r.unwrap();
left.iter()
.fold(Attributes::new(), |mut new_attributes, (k, v)| {
if !right.contains_key(k) {
new_attributes.insert(k.clone(), v.clone());
}
new_attributes
})
left.iter().fold(Attributes::new(), |mut new_attributes, (k, v)| {
if !right.contains_key(k) {
new_attributes.insert(k.clone(), v.clone());
}
new_attributes
})
}
pub fn invert_attributes(attr: Attributes, base: Attributes) -> Attributes {
let base_inverted = base
.iter()
.fold(Attributes::new(), |mut attributes, (k, v)| {
if base.get(k) != attr.get(k) && attr.contains_key(k) {
attributes.insert(k.clone(), v.clone());
}
attributes
});
let base_inverted = base.iter().fold(Attributes::new(), |mut attributes, (k, v)| {
if base.get(k) != attr.get(k) && attr.contains_key(k) {
attributes.insert(k.clone(), v.clone());
}
attributes
});
let inverted = attr.iter().fold(base_inverted, |mut attributes, (k, _)| {
if base.get(k) != attr.get(k) && !base.contains_key(k) {

View File

@ -21,9 +21,7 @@ impl<'de> Deserialize<'de> for AttributeValue {
impl<'de> Visitor<'de> for OperationSeqVisitor {
type Value = AttributeValue;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string")
}
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a string") }
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where

View File

@ -1,33 +1,9 @@
use crate::core::{Attribute, AttributeKey, AttributeValue, Attributes, REMOVE_FLAG};
#![allow(non_snake_case)]
use crate::core::{Attribute, Attributes};
pub struct AttributeBuilder {
inner: Attributes,
}
macro_rules! impl_bool_attribute {
($name: ident,$key: expr) => {
pub fn $name(self, value: bool) -> Self {
let value = match value {
true => "true",
false => REMOVE_FLAG,
};
self.insert($key, value)
}
};
}
macro_rules! impl_str_attribute {
($name: ident,$key: expr) => {
pub fn $name(self, s: &str, value: bool) -> Self {
let value = match value {
true => s,
false => REMOVE_FLAG,
};
self.insert($key, value)
}
};
}
impl AttributeBuilder {
pub fn new() -> Self {
Self {
@ -40,23 +16,5 @@ impl AttributeBuilder {
self
}
pub fn insert<T: Into<AttributeValue>>(mut self, key: AttributeKey, value: T) -> Self {
self.inner.add(key.value(value));
self
}
pub fn remove<T: Into<String>>(mut self, key: AttributeKey) -> Self {
self.inner.add(key.value(REMOVE_FLAG));
self
}
// AttributeBuilder::new().bold(true).build()
impl_bool_attribute!(bold, AttributeKey::Bold);
impl_bool_attribute!(italic, AttributeKey::Italic);
impl_bool_attribute!(underline, AttributeKey::Underline);
impl_bool_attribute!(strike_through, AttributeKey::StrikeThrough);
impl_str_attribute!(link, AttributeKey::Link);
// impl_str_attribute!(header, AttributeKey::Header);
pub fn build(self) -> Attributes { self.inner }
}

View File

@ -1,15 +1,11 @@
use crate::core::{Attributes, Delta, Operation};
use crate::core::{plain_attributes, Attributes, Delta, Operation};
pub struct DeltaBuilder {
delta: Delta,
}
impl DeltaBuilder {
pub fn new() -> Self {
Self {
delta: Delta::new(),
}
}
pub fn new() -> Self { Self { delta: Delta::new() } }
pub fn retain_with_attributes(mut self, n: usize, attrs: Attributes) -> Self {
self.delta.retain(n, attrs);
@ -17,7 +13,7 @@ impl DeltaBuilder {
}
pub fn retain(mut self, n: usize) -> Self {
self.delta.retain(n, Attributes::empty());
self.delta.retain(n, plain_attributes());
self
}
@ -32,7 +28,7 @@ impl DeltaBuilder {
}
pub fn insert(mut self, s: &str) -> Self {
self.delta.insert(s, Attributes::empty());
self.delta.insert(s, plain_attributes());
self
}

View File

@ -50,9 +50,7 @@ impl<'a> OpCursor<'a> {
let mut consume_len = 0;
while find_op.is_none() && next_op.is_some() {
let op = next_op.take().unwrap();
let interval = self
.next_iv_before(force_end)
.unwrap_or(Interval::new(0, 0));
let interval = self.next_iv_before(force_end).unwrap_or(Interval::new(0, 0));
// cache the op if the interval is empty. e.g. last_op_before(Some(0))
if interval.is_empty() {
@ -188,9 +186,7 @@ fn check_bound(current: usize, target: usize) -> Result<(), OTError> {
debug_assert!(current <= target);
if current > target {
let msg = format!("{} should be greater than current: {}", target, current);
return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength)
.msg(&msg)
.build());
return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength).msg(&msg).build());
}
Ok(())
}

View File

@ -102,7 +102,7 @@ impl Delta {
}
}
pub fn insert(&mut self, s: &str, attrs: Attributes) {
pub fn insert(&mut self, s: &str, attributes: Attributes) {
if s.is_empty() {
return;
}
@ -111,18 +111,18 @@ impl Delta {
let new_last = match self.ops.as_mut_slice() {
[.., Operation::Insert(insert)] => {
//
insert.merge_or_new_op(s, attrs)
insert.merge_or_new_op(s, attributes)
},
[.., Operation::Insert(pre_insert), Operation::Delete(_)] => {
//
pre_insert.merge_or_new_op(s, attrs)
pre_insert.merge_or_new_op(s, attributes)
},
[.., op_last @ Operation::Delete(_)] => {
let new_last = op_last.clone();
*op_last = OpBuilder::insert(s).attributes(attrs).build();
*op_last = OpBuilder::insert(s).attributes(attributes).build();
Some(new_last)
},
_ => Some(OpBuilder::insert(s).attributes(attrs).build()),
_ => Some(OpBuilder::insert(s).attributes(attributes).build()),
};
match new_last {
@ -131,7 +131,7 @@ impl Delta {
}
}
pub fn retain(&mut self, n: usize, attrs: Attributes) {
pub fn retain(&mut self, n: usize, attributes: Attributes) {
if n == 0 {
return;
}
@ -139,11 +139,11 @@ impl Delta {
self.target_len += n as usize;
if let Some(Operation::Retain(retain)) = self.ops.last_mut() {
if let Some(new_op) = retain.merge_or_new_op(n, attrs) {
if let Some(new_op) = retain.merge_or_new(n, attributes) {
self.ops.push(new_op);
}
} else {
self.ops.push(OpBuilder::retain(n).attributes(attrs).build());
self.ops.push(OpBuilder::retain(n).attributes(attributes).build());
}
}

View File

@ -32,9 +32,7 @@ impl<'de> Deserialize<'de> for Delta {
impl<'de> Visitor<'de> for OperationSeqVisitor {
type Value = Delta;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a sequence") }
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where

View File

@ -39,9 +39,7 @@ impl<'a> DeltaIter<'a> {
pub fn next_op(&mut self) -> Option<Operation> { self.cursor.next() }
pub fn next_op_with_len(&mut self, len: usize) -> Option<Operation> {
self.cursor.next_with_len(Some(len))
}
pub fn next_op_with_len(&mut self, len: usize) -> Option<Operation> { self.cursor.next_with_len(Some(len)) }
// find next op contains NEW_LINE
pub fn next_op_with_newline(&mut self) -> Option<(Operation, usize)> {
@ -210,9 +208,7 @@ impl OpNewline {
pub fn is_not_found(&self) -> bool { self == &OpNewline::NotFound }
pub fn is_contain(&self) -> bool {
self.is_start() || self.is_end() || self.is_equal() || self == &OpNewline::Contain
}
pub fn is_contain(&self) -> bool { self.is_start() || self.is_end() || self.is_equal() || self == &OpNewline::Contain }
pub fn is_equal(&self) -> bool { self == &OpNewline::Equal }
}

View File

@ -33,9 +33,7 @@ impl Interval {
pub fn contains(&self, val: usize) -> bool { self.start <= val && val < self.end }
pub fn contains_range(&self, start: usize, end: usize) -> bool {
!self.intersect(Interval::new(start, end)).is_empty()
}
pub fn contains_range(&self, start: usize, end: usize) -> bool { !self.intersect(Interval::new(start, end)).is_empty() }
pub fn is_after(&self, val: usize) -> bool { self.start > val }
@ -101,9 +99,7 @@ impl std::default::Default for Interval {
}
impl fmt::Display for Interval {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}, {})", self.start(), self.end())
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[{}, {})", self.start(), self.end()) }
}
impl fmt::Debug for Interval {
@ -122,15 +118,11 @@ impl From<RangeTo<usize>> for Interval {
}
impl From<RangeInclusive<usize>> for Interval {
fn from(src: RangeInclusive<usize>) -> Interval {
Interval::new(*src.start(), src.end().saturating_add(1))
}
fn from(src: RangeInclusive<usize>) -> Interval { Interval::new(*src.start(), src.end().saturating_add(1)) }
}
impl From<RangeToInclusive<usize>> for Interval {
fn from(src: RangeToInclusive<usize>) -> Interval {
Interval::new(0, src.end.saturating_add(1))
}
fn from(src: RangeToInclusive<usize>) -> Interval { Interval::new(0, src.end.saturating_add(1)) }
}
#[cfg(test)]
@ -186,29 +178,18 @@ mod tests {
#[test]
fn intersect() {
assert_eq!(
Interval::new(2, 3),
Interval::new(1, 3).intersect(Interval::new(2, 4))
);
assert!(Interval::new(1, 2)
.intersect(Interval::new(2, 43))
.is_empty());
assert_eq!(Interval::new(2, 3), Interval::new(1, 3).intersect(Interval::new(2, 4)));
assert!(Interval::new(1, 2).intersect(Interval::new(2, 43)).is_empty());
}
#[test]
fn prefix() {
assert_eq!(
Interval::new(1, 2),
Interval::new(1, 4).prefix(Interval::new(2, 3))
);
assert_eq!(Interval::new(1, 2), Interval::new(1, 4).prefix(Interval::new(2, 3)));
}
#[test]
fn suffix() {
assert_eq!(
Interval::new(3, 4),
Interval::new(1, 4).suffix(Interval::new(2, 3))
);
assert_eq!(Interval::new(3, 4), Interval::new(1, 4).suffix(Interval::new(2, 3)));
}
#[test]

View File

@ -42,9 +42,7 @@ impl Operation {
pub fn has_attribute(&self) -> bool { !self.get_attributes().is_empty() }
pub fn contain_attribute(&self, attribute: &Attribute) -> bool {
self.get_attributes().contains_key(&attribute.key)
}
pub fn contain_attribute(&self, attribute: &Attribute) -> bool { self.get_attributes().contains_key(&attribute.key) }
pub fn len(&self) -> usize {
match self {
@ -72,11 +70,7 @@ impl Operation {
},
Operation::Insert(insert) => {
let attributes = self.get_attributes();
left = Some(
OpBuilder::insert(&insert.s[0..index])
.attributes(attributes.clone())
.build(),
);
left = Some(OpBuilder::insert(&insert.s[0..index]).attributes(attributes.clone()).build());
right = Some(
OpBuilder::insert(&insert.s[index..insert.num_chars()])
.attributes(attributes)
@ -99,13 +93,9 @@ impl Operation {
OpBuilder::insert("").build()
} else {
let chars = insert.chars().skip(interval.start);
let s = &chars
.take(min(interval.size(), insert.num_chars()))
.collect::<String>();
let s = &chars.take(min(interval.size(), insert.num_chars())).collect::<String>();
OpBuilder::insert(s)
.attributes(insert.attributes.clone())
.build()
OpBuilder::insert(s).attributes(insert.attributes.clone()).build()
}
},
};
@ -166,22 +156,12 @@ pub struct Retain {
}
impl fmt::Display for Retain {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!(
"retain: {}, attributes: {}",
self.n, self.attributes
))
}
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_fmt(format_args!("retain: {}, attributes: {}", self.n, self.attributes)) }
}
impl Retain {
pub fn merge_or_new_op(&mut self, n: usize, attributes: Attributes) -> Option<Operation> {
log::debug!(
"merge_retain_or_new_op: len: {:?}, l: {} - r: {}",
n,
self.attributes,
attributes
);
pub fn merge_or_new(&mut self, n: usize, attributes: Attributes) -> Option<Operation> {
log::debug!("merge_retain_or_new_op: len: {:?}, l: {} - r: {}", n, self.attributes, attributes);
if self.attributes == attributes {
self.n += n;
@ -232,10 +212,7 @@ impl fmt::Display for Insert {
}
}
f.write_fmt(format_args!(
"insert: {}, attributes: {}",
s, self.attributes
))
f.write_fmt(format_args!("insert: {}, attributes: {}", s, self.attributes))
}
}

View File

@ -7,12 +7,7 @@ pub struct OTError {
}
impl OTError {
pub fn new(code: OTErrorCode, msg: &str) -> OTError {
Self {
code,
msg: msg.to_owned(),
}
}
pub fn new(code: OTErrorCode, msg: &str) -> OTError { Self { code, msg: msg.to_owned() } }
}
impl fmt::Display for OTError {
@ -24,11 +19,7 @@ impl Error for OTError {
}
impl std::convert::From<serde_json::Error> for OTError {
fn from(error: serde_json::Error) -> Self {
ErrorBuilder::new(OTErrorCode::SerdeError)
.error(error)
.build()
}
fn from(error: serde_json::Error) -> Self { ErrorBuilder::new(OTErrorCode::SerdeError).error(error).build() }
}
#[derive(Debug, Clone)]
@ -68,7 +59,5 @@ impl ErrorBuilder {
self
}
pub fn build(mut self) -> OTError {
OTError::new(self.code, &self.msg.take().unwrap_or("".to_owned()))
}
pub fn build(mut self) -> OTError { OTError::new(self.code, &self.msg.take().unwrap_or("".to_owned())) }
}

View File

@ -39,10 +39,7 @@ fn attributes_bold_added_and_invert_partial_suffix() {
Bold(0, Interval::new(0, 4), true),
AssertOpsJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
Bold(0, Interval::new(2, 4), false),
AssertOpsJson(
0,
r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#,
),
AssertOpsJson(0, r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#),
];
OpTester::new().run_script(ops);
}
@ -54,10 +51,7 @@ fn attributes_bold_added_and_invert_partial_suffix2() {
Bold(0, Interval::new(0, 4), true),
AssertOpsJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
Bold(0, Interval::new(2, 4), false),
AssertOpsJson(
0,
r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#,
),
AssertOpsJson(0, r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#),
Bold(0, Interval::new(2, 4), true),
AssertOpsJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
];
@ -69,10 +63,7 @@ fn attributes_bold_added_with_new_line() {
let ops = vec![
Insert(0, "123456", 0),
Bold(0, Interval::new(0, 6), true),
AssertOpsJson(
0,
r#"[{"insert":"123456","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
),
AssertOpsJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}},{"insert":"\n"}]"#),
Insert(0, "\n", 3),
AssertOpsJson(
0,
@ -99,10 +90,7 @@ fn attributes_bold_added_and_invert_partial_prefix() {
Bold(0, Interval::new(0, 4), true),
AssertOpsJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
Bold(0, Interval::new(0, 2), false),
AssertOpsJson(
0,
r#"[{"insert":"12"},{"insert":"34","attributes":{"bold":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"12"},{"insert":"34","attributes":{"bold":"true"}}]"#),
];
OpTester::new().run_script(ops);
}
@ -112,15 +100,9 @@ fn attributes_bold_added_consecutive() {
let ops = vec![
Insert(0, "1234", 0),
Bold(0, Interval::new(0, 1), true),
AssertOpsJson(
0,
r#"[{"insert":"1","attributes":{"bold":"true"}},{"insert":"234"}]"#,
),
AssertOpsJson(0, r#"[{"insert":"1","attributes":{"bold":"true"}},{"insert":"234"}]"#),
Bold(0, Interval::new(1, 2), true),
AssertOpsJson(
0,
r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#,
),
AssertOpsJson(0, r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#),
];
OpTester::new().run_script(ops);
}
@ -239,10 +221,7 @@ fn attributes_bold_added_italic_delete() {
"#,
),
Delete(0, Interval::new(0, 5)),
AssertOpsJson(
0,
r#"[{"insert":"67"},{"insert":"89","attributes":{"bold":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"67"},{"insert":"89","attributes":{"bold":"true"}}]"#),
];
OpTester::new().run_script(ops);
@ -387,10 +366,7 @@ fn attributes_replace_with_text() {
InsertBold(0, "123456", Interval::new(0, 6)),
AssertOpsJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
Replace(0, Interval::new(0, 3), "ab"),
AssertOpsJson(
0,
r#"[{"insert":"ab"},{"insert":"456","attributes":{"bold":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"ab"},{"insert":"456","attributes":{"bold":"true"}}]"#),
];
OpTester::new().run_script(ops);
@ -400,11 +376,8 @@ fn attributes_replace_with_text() {
fn attributes_header_insert_newline_at_middle() {
let ops = vec![
Insert(0, "123456", 0),
Header(0, Interval::new(0, 6), 1, true),
AssertOpsJson(
0,
r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":"1"}}]"#,
),
Header(0, Interval::new(0, 6), 1),
AssertOpsJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":"1"}}]"#),
Insert(0, "\n", 3),
AssertOpsJson(
0,
@ -419,7 +392,7 @@ fn attributes_header_insert_newline_at_middle() {
fn attributes_header_insert_double_newline_at_middle() {
let ops = vec![
Insert(0, "123456", 0),
Header(0, Interval::new(0, 6), 1, true),
Header(0, Interval::new(0, 6), 1),
Insert(0, "\n", 3),
AssertOpsJson(
0,
@ -444,7 +417,7 @@ fn attributes_header_insert_double_newline_at_middle() {
fn attributes_header_insert_newline_at_trailing() {
let ops = vec![
Insert(0, "123456", 0),
Header(0, Interval::new(0, 6), 1, true),
Header(0, Interval::new(0, 6), 1),
Insert(0, "\n", 6),
AssertOpsJson(
0,
@ -459,7 +432,7 @@ fn attributes_header_insert_newline_at_trailing() {
fn attributes_header_insert_double_newline_at_trailing() {
let ops = vec![
Insert(0, "123456", 0),
Header(0, Interval::new(0, 6), 1, true),
Header(0, Interval::new(0, 6), 1),
Insert(0, "\n", 6),
Insert(0, "\n", 7),
AssertOpsJson(
@ -475,7 +448,7 @@ fn attributes_header_insert_double_newline_at_trailing() {
fn attributes_link_added() {
let ops = vec![
Insert(0, "123456", 0),
Link(0, Interval::new(0, 6), "https://appflowy.io", true),
Link(0, Interval::new(0, 6), "https://appflowy.io"),
AssertOpsJson(
0,
r#"[{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
@ -489,7 +462,7 @@ fn attributes_link_added() {
fn attributes_link_format_with_bold() {
let ops = vec![
Insert(0, "123456", 0),
Link(0, Interval::new(0, 6), "https://appflowy.io", true),
Link(0, Interval::new(0, 6), "https://appflowy.io"),
Bold(0, Interval::new(0, 3), true),
AssertOpsJson(
0,
@ -508,7 +481,7 @@ fn attributes_link_format_with_bold() {
fn attributes_link_insert_char_at_head() {
let ops = vec![
Insert(0, "123456", 0),
Link(0, Interval::new(0, 6), "https://appflowy.io", true),
Link(0, Interval::new(0, 6), "https://appflowy.io"),
AssertOpsJson(
0,
r#"[{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
@ -527,7 +500,7 @@ fn attributes_link_insert_char_at_head() {
fn attributes_link_insert_char_at_middle() {
let ops = vec![
Insert(0, "1256", 0),
Link(0, Interval::new(0, 4), "https://appflowy.io", true),
Link(0, Interval::new(0, 4), "https://appflowy.io"),
Insert(0, "34", 2),
AssertOpsJson(
0,
@ -542,7 +515,7 @@ fn attributes_link_insert_char_at_middle() {
fn attributes_link_insert_char_at_trailing() {
let ops = vec![
Insert(0, "123456", 0),
Link(0, Interval::new(0, 6), "https://appflowy.io", true),
Link(0, Interval::new(0, 6), "https://appflowy.io"),
AssertOpsJson(
0,
r#"[{"insert":"123456","attributes":{"link":"https://appflowy.io"}},{"insert":"\n"}]"#,
@ -561,7 +534,7 @@ fn attributes_link_insert_char_at_trailing() {
fn attributes_link_insert_newline_at_middle() {
let ops = vec![
Insert(0, "123456", 0),
Link(0, Interval::new(0, 6), "https://appflowy.io", true),
Link(0, Interval::new(0, 6), "https://appflowy.io"),
Insert(0, NEW_LINE, 3),
AssertOpsJson(
0,
@ -593,7 +566,7 @@ fn attributes_link_auto_format_exist() {
let site = "https://appflowy.io";
let ops = vec![
Insert(0, site, 0),
Link(0, Interval::new(0, site.len()), site, true),
Link(0, Interval::new(0, site.len()), site),
Insert(0, WHITESPACE, site.len()),
AssertOpsJson(
0,
@ -609,7 +582,7 @@ fn attributes_link_auto_format_exist2() {
let site = "https://appflowy.io";
let ops = vec![
Insert(0, site, 0),
Link(0, Interval::new(0, site.len() / 2), site, true),
Link(0, Interval::new(0, site.len() / 2), site),
Insert(0, WHITESPACE, site.len()),
AssertOpsJson(
0,
@ -625,10 +598,7 @@ fn attributes_bullet_added() {
let ops = vec![
Insert(0, "12", 0),
Bullet(0, Interval::new(0, 1), true),
AssertOpsJson(
0,
r#"[{"insert":"12"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"12"},{"insert":"\n","attributes":{"bullet":"true"}}]"#),
];
OpTester::new().run_script_with_newline(ops);
@ -639,15 +609,9 @@ fn attributes_bullet_added_2() {
let ops = vec![
Insert(0, "1", 0),
Bullet(0, Interval::new(0, 1), true),
AssertOpsJson(
0,
r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}}]"#),
Insert(0, NEW_LINE, 1),
AssertOpsJson(
0,
r#"[{"insert":"1"},{"insert":"\n\n","attributes":{"bullet":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"1"},{"insert":"\n\n","attributes":{"bullet":"true"}}]"#),
Insert(0, "2", 2),
AssertOpsJson(
0,
@ -697,10 +661,7 @@ fn attributes_preserve_block_when_insert_newline_inside() {
Insert(0, "12", 0),
Bullet(0, Interval::new(0, 2), true),
Insert(0, NEW_LINE, 2),
AssertOpsJson(
0,
r#"[{"insert":"12"},{"insert":"\n\n","attributes":{"bullet":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"12"},{"insert":"\n\n","attributes":{"bullet":"true"}}]"#),
Insert(0, "34", 3),
AssertOpsJson(
0,
@ -735,17 +696,14 @@ fn attributes_preserve_block_when_insert_newline_inside() {
fn attributes_preserve_header_format_on_merge() {
let ops = vec![
Insert(0, "123456", 0),
Header(0, Interval::new(0, 6), 1, true),
Header(0, Interval::new(0, 6), 1),
Insert(0, NEW_LINE, 3),
AssertOpsJson(
0,
r#"[{"insert":"123"},{"insert":"\n","attributes":{"header":"1"}},{"insert":"456"},{"insert":"\n","attributes":{"header":"1"}}]"#,
),
Delete(0, Interval::new(3, 4)),
AssertOpsJson(
0,
r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":"1"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":"1"}}]"#),
];
OpTester::new().run_script_with_newline(ops);
@ -762,10 +720,7 @@ fn attributes_preserve_list_format_on_merge() {
r#"[{"insert":"123"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
),
Delete(0, Interval::new(3, 4)),
AssertOpsJson(
0,
r#"[{"insert":"123456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#),
];
OpTester::new().run_script_with_newline(ops);

View File

@ -28,10 +28,10 @@ pub enum TestOp {
Italic(usize, Interval, bool),
#[display(fmt = "Header")]
Header(usize, Interval, usize, bool),
Header(usize, Interval, usize),
#[display(fmt = "Link")]
Link(usize, Interval, &'static str, bool),
Link(usize, Interval, &'static str),
#[display(fmt = "Bullet")]
Bullet(usize, Interval, bool),
@ -93,48 +93,34 @@ impl OpTester {
TestOp::InsertBold(delta_i, s, iv) => {
let document = &mut self.documents[*delta_i];
document.insert(iv.start, s).unwrap();
document
.format(*iv, AttributeKey::Bold.value(true))
.unwrap();
document.format(*iv, Attribute::Bold(true)).unwrap();
},
TestOp::Bold(delta_i, iv, enable) => {
let document = &mut self.documents[*delta_i];
let attribute = match *enable {
true => AttributeKey::Bold.value(true),
false => AttributeKey::Bold.remove(),
};
let attribute = Attribute::Bold(*enable);
document.format(*iv, attribute).unwrap();
},
TestOp::Italic(delta_i, iv, enable) => {
let document = &mut self.documents[*delta_i];
let attribute = match *enable {
true => AttributeKey::Italic.value("true"),
false => AttributeKey::Italic.remove(),
true => Attribute::Italic(true),
false => Attribute::Italic(false),
};
document.format(*iv, attribute).unwrap();
},
TestOp::Header(delta_i, iv, level, enable) => {
TestOp::Header(delta_i, iv, level) => {
let document = &mut self.documents[*delta_i];
let attribute = match *enable {
true => AttributeKey::Header.value(level),
false => AttributeKey::Header.remove(),
};
let attribute = Attribute::Header(*level);
document.format(*iv, attribute).unwrap();
},
TestOp::Link(delta_i, iv, link, enable) => {
TestOp::Link(delta_i, iv, link) => {
let document = &mut self.documents[*delta_i];
let attribute = match *enable {
true => AttributeKey::Link.value(link.to_owned()),
false => AttributeKey::Link.remove(),
};
let attribute = Attribute::Link(link.to_owned());
document.format(*iv, attribute).unwrap();
},
TestOp::Bullet(delta_i, iv, enable) => {
let document = &mut self.documents[*delta_i];
let attribute = match *enable {
true => AttributeKey::Bullet.value("true"),
false => AttributeKey::Bullet.remove(),
};
let attribute = Attribute::Bullet(*enable);
document.format(*iv, attribute).unwrap();
},
TestOp::Transform(delta_a_i, delta_b_i) => {
@ -236,9 +222,7 @@ impl Default for Rng {
impl Rng {
pub fn from_seed(seed: [u8; 32]) -> Self { Rng(StdRng::from_seed(seed)) }
pub fn gen_string(&mut self, len: usize) -> String {
(0..len).map(|_| self.0.gen::<char>()).collect()
}
pub fn gen_string(&mut self, len: usize) -> String { (0..len).map(|_| self.0.gen::<char>()).collect() }
pub fn gen_delta(&mut self, s: &str) -> Delta {
let mut delta = Delta::default();
@ -265,10 +249,7 @@ impl Rng {
}
}
if self.0.gen_range(0.0, 1.0) < 0.3 {
delta.insert(
&("1".to_owned() + &self.gen_string(10)),
Attributes::default(),
);
delta.insert(&("1".to_owned() + &self.gen_string(10)), Attributes::default());
}
delta
}

View File

@ -71,10 +71,7 @@ fn delta_get_ops_in_interval_2() {
vec![OpBuilder::insert("23").build()]
);
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(0, 3)).ops(),
vec![insert_a.clone()]
);
assert_eq!(DeltaIter::from_interval(&delta, Interval::new(0, 3)).ops(), vec![insert_a.clone()]);
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(0, 4)).ops(),
@ -114,25 +111,13 @@ fn delta_get_ops_in_interval_4() {
delta.ops.push(insert_b.clone());
delta.ops.push(insert_c.clone());
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(0, 2)).ops(),
vec![insert_a]
);
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(2, 4)).ops(),
vec![insert_b]
);
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(4, 6)).ops(),
vec![insert_c]
);
assert_eq!(DeltaIter::from_interval(&delta, Interval::new(0, 2)).ops(), vec![insert_a]);
assert_eq!(DeltaIter::from_interval(&delta, Interval::new(2, 4)).ops(), vec![insert_b]);
assert_eq!(DeltaIter::from_interval(&delta, Interval::new(4, 6)).ops(), vec![insert_c]);
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(2, 5)).ops(),
vec![
OpBuilder::insert("34").build(),
OpBuilder::insert("5").build()
]
vec![OpBuilder::insert("34").build(), OpBuilder::insert("5").build()]
);
}
@ -145,10 +130,7 @@ fn delta_get_ops_in_interval_5() {
delta.ops.push(insert_b.clone());
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(4, 8)).ops(),
vec![
OpBuilder::insert("56").build(),
OpBuilder::insert("78").build()
]
vec![OpBuilder::insert("56").build(), OpBuilder::insert("78").build()]
);
// assert_eq!(
@ -182,10 +164,7 @@ fn delta_get_ops_in_interval_7() {
assert_eq!(iter_1.next_op().unwrap(), OpBuilder::retain(3).build());
let mut iter_2 = DeltaIter::new(&delta);
assert_eq!(
iter_2.next_op_with_len(2).unwrap(),
OpBuilder::insert("12").build()
);
assert_eq!(iter_2.next_op_with_len(2).unwrap(), OpBuilder::insert("12").build());
assert_eq!(iter_2.next_op().unwrap(), OpBuilder::insert("345").build());
assert_eq!(iter_2.next_op().unwrap(), OpBuilder::retain(3).build());
@ -209,10 +188,7 @@ fn delta_seek_2() {
delta.add(OpBuilder::insert("12345").build());
let mut iter = DeltaIter::new(&delta);
assert_eq!(
iter.next_op_with_len(1).unwrap(),
OpBuilder::insert("1").build()
);
assert_eq!(iter.next_op_with_len(1).unwrap(), OpBuilder::insert("1").build());
}
#[test]
@ -221,20 +197,11 @@ fn delta_seek_3() {
delta.add(OpBuilder::insert("12345").build());
let mut iter = DeltaIter::new(&delta);
assert_eq!(
iter.next_op_with_len(2).unwrap(),
OpBuilder::insert("12").build()
);
assert_eq!(iter.next_op_with_len(2).unwrap(), OpBuilder::insert("12").build());
assert_eq!(
iter.next_op_with_len(2).unwrap(),
OpBuilder::insert("34").build()
);
assert_eq!(iter.next_op_with_len(2).unwrap(), OpBuilder::insert("34").build());
assert_eq!(
iter.next_op_with_len(2).unwrap(),
OpBuilder::insert("5").build()
);
assert_eq!(iter.next_op_with_len(2).unwrap(), OpBuilder::insert("5").build());
assert_eq!(iter.next_op_with_len(1), None);
}
@ -246,21 +213,18 @@ fn delta_seek_4() {
let mut iter = DeltaIter::new(&delta);
iter.seek::<CharMetric>(3);
assert_eq!(
iter.next_op_with_len(2).unwrap(),
OpBuilder::insert("45").build()
);
assert_eq!(iter.next_op_with_len(2).unwrap(), OpBuilder::insert("45").build());
}
#[test]
fn delta_seek_5() {
let mut delta = Delta::default();
let attributes = AttributeBuilder::new().bold(true).italic(true).build();
delta.add(
OpBuilder::insert("1234")
.attributes(attributes.clone())
.build(),
);
let attributes = AttributeBuilder::new()
.add(Attribute::Bold(true))
.add(Attribute::Italic(true))
.build();
delta.add(OpBuilder::insert("1234").attributes(attributes.clone()).build());
delta.add(OpBuilder::insert("\n").build());
let mut iter = DeltaIter::new(&delta);
@ -280,10 +244,7 @@ fn delta_next_op_len_test() {
let mut iter = DeltaIter::new(&delta);
iter.seek::<CharMetric>(3);
assert_eq!(iter.next_op_len().unwrap(), 2);
assert_eq!(
iter.next_op_with_len(1).unwrap(),
OpBuilder::insert("4").build()
);
assert_eq!(iter.next_op_with_len(1).unwrap(), OpBuilder::insert("4").build());
assert_eq!(iter.next_op_len().unwrap(), 1);
assert_eq!(iter.next_op().unwrap(), OpBuilder::insert("5").build());
}
@ -295,10 +256,7 @@ fn delta_next_op_len_test2() {
let mut iter = DeltaIter::new(&delta);
assert_eq!(iter.next_op_len().unwrap(), 5);
assert_eq!(
iter.next_op_with_len(5).unwrap(),
OpBuilder::insert("12345").build()
);
assert_eq!(iter.next_op_with_len(5).unwrap(), OpBuilder::insert("12345").build());
assert_eq!(iter.next_op_len(), None);
}
@ -321,10 +279,7 @@ fn delta_next_op_with_len_cross_op_return_last() {
let mut iter = DeltaIter::new(&delta);
iter.seek::<CharMetric>(4);
assert_eq!(iter.next_op_len().unwrap(), 1);
assert_eq!(
iter.next_op_with_len(2).unwrap(),
OpBuilder::retain(1).build()
);
assert_eq!(iter.next_op_with_len(2).unwrap(), OpBuilder::retain(1).build());
}
#[test]
@ -523,7 +478,7 @@ fn transform2() {
fn delta_transform_test() {
let mut a = Delta::default();
let mut a_s = String::new();
a.insert("123", AttributeBuilder::new().bold(true).build());
a.insert("123", AttributeBuilder::new().add(Attribute::Bold(true)).build());
a_s = a.apply(&a_s).unwrap();
assert_eq!(&a_s, "123");
@ -625,10 +580,7 @@ fn delta_invert_no_attribute_delta_with_attribute_delta() {
Insert(0, "123", 0),
Insert(1, "4567", 0),
Bold(1, Interval::new(0, 3), true),
AssertOpsJson(
1,
r#"[{"insert":"456","attributes":{"bold":"true"}},{"insert":"7"}]"#,
),
AssertOpsJson(1, r#"[{"insert":"456","attributes":{"bold":"true"}},{"insert":"7"}]"#),
Invert(0, 1),
AssertOpsJson(0, r#"[{"insert":"123"}]"#),
];

View File

@ -2,7 +2,10 @@ use flowy_ot::{client::Document, core::*};
#[test]
fn operation_insert_serialize_test() {
let attributes = AttributeBuilder::new().bold(true).italic(true).build();
let attributes = AttributeBuilder::new()
.add(Attribute::Bold(true))
.add(Attribute::Italic(true))
.build();
let operation = OpBuilder::insert("123").attributes(attributes).build();
let json = serde_json::to_string(&operation).unwrap();
eprintln!("{}", json);
@ -32,7 +35,10 @@ fn operation_delete_serialize_test() {
fn delta_serialize_test() {
let mut delta = Delta::default();
let attributes = AttributeBuilder::new().bold(true).italic(true).build();
let attributes = AttributeBuilder::new()
.add(Attribute::Bold(true))
.add(Attribute::Italic(true))
.build();
let retain = OpBuilder::insert("123").attributes(attributes).build();
delta.add(retain);

View File

@ -8,11 +8,7 @@ use flowy_ot::{
#[test]
fn history_insert_undo() {
let ops = vec![
Insert(0, "123", 0),
Undo(0),
AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
];
let ops = vec![Insert(0, "123", 0), Undo(0), AssertOpsJson(0, r#"[{"insert":"\n"}]"#)];
OpTester::new().run_script_with_newline(ops);
}
@ -93,10 +89,7 @@ fn history_bold_redo() {
Undo(0),
AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
Redo(0),
AssertOpsJson(
0,
r#" [{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
),
AssertOpsJson(0, r#" [{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#),
];
OpTester::new().run_script_with_newline(ops);
}
@ -110,10 +103,7 @@ fn history_bold_redo_with_lagging() {
Undo(0),
AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
Redo(0),
AssertOpsJson(
0,
r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
),
AssertOpsJson(0, r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#),
];
OpTester::new().run_script_with_newline(ops);
}
@ -226,10 +216,7 @@ fn history_replace_undo_with_lagging() {
"#,
),
Undo(0),
AssertOpsJson(
0,
r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
),
AssertOpsJson(0, r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#),
];
OpTester::new().run_script_with_newline(ops);
}
@ -257,7 +244,7 @@ fn history_replace_redo() {
fn history_header_added_undo() {
let ops = vec![
Insert(0, "123456", 0),
Header(0, Interval::new(0, 6), 1, true),
Header(0, Interval::new(0, 6), 1),
Insert(0, "\n", 3),
Insert(0, "\n", 4),
Undo(0),
@ -278,7 +265,7 @@ fn history_link_added_undo() {
let ops = vec![
Insert(0, site, 0),
Wait(RECORD_THRESHOLD),
Link(0, Interval::new(0, site.len()), site, true),
Link(0, Interval::new(0, site.len()), site),
Undo(0),
AssertOpsJson(0, r#"[{"insert":"https://appflowy.io\n"}]"#),
Redo(0),
@ -347,10 +334,7 @@ fn history_bullet_undo_with_lagging() {
r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"2"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
),
Undo(0),
AssertOpsJson(
0,
r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"1"},{"insert":"\n","attributes":{"bullet":"true"}}]"#),
Undo(0),
AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
Redo(0),
@ -377,10 +361,7 @@ fn history_undo_attribute_on_merge_between_line() {
r#"[{"insert":"123"},{"insert":"\n","attributes":{"bullet":"true"}},{"insert":"456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
),
Delete(0, Interval::new(3, 4)), // delete the newline
AssertOpsJson(
0,
r#"[{"insert":"123456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#,
),
AssertOpsJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#),
Undo(0),
AssertOpsJson(
0,

View File

@ -1,12 +1,5 @@
use crate::errors::*;
use diesel::{
dsl::sql,
expression::SqlLiteral,
query_dsl::LoadQuery,
Connection,
RunQueryDsl,
SqliteConnection,
};
use diesel::{dsl::sql, expression::SqlLiteral, query_dsl::LoadQuery, Connection, RunQueryDsl, SqliteConnection};
pub trait ConnectionExtension: Connection {
fn query<ST, T>(&self, query: &str) -> Result<T>
@ -24,7 +17,5 @@ impl ConnectionExtension for SqliteConnection {
Ok(sql::<ST>(query).get_result(self)?)
}
fn exec(&self, query: impl AsRef<str>) -> Result<usize> {
Ok(SqliteConnection::execute(self, query.as_ref())?)
}
fn exec(&self, query: impl AsRef<str>) -> Result<usize> { Ok(SqliteConnection::execute(self, query.as_ref())?) }
}

View File

@ -21,10 +21,7 @@ impl Database {
}
let pool = ConnectionPool::new(pool_config, &uri)?;
Ok(Self {
uri,
pool: Arc::new(pool),
})
Ok(Self { uri, pool: Arc::new(pool) })
}
pub fn get_uri(&self) -> &str { &self.uri }

View File

@ -1,10 +1,4 @@
use error_chain::{
error_chain,
error_chain_processing,
impl_error_chain_kind,
impl_error_chain_processed,
impl_extract_backtrace,
};
use error_chain::{error_chain, error_chain_processing, impl_error_chain_kind, impl_error_chain_processed, impl_extract_backtrace};
error_chain! {
errors {

View File

@ -119,9 +119,7 @@ impl ManageConnection for ConnectionManager {
fn connect(&self) -> Result<Self::Connection> { Ok(SqliteConnection::establish(&self.db_uri)?) }
fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> {
Ok(conn.execute("SELECT 1").map(|_| ())?)
}
fn is_valid(&self, conn: &mut Self::Connection) -> Result<()> { Ok(conn.execute("SELECT 1").map(|_| ())?) }
fn has_broken(&self, _conn: &mut Self::Connection) -> bool { false }
}

View File

@ -24,12 +24,7 @@ pub trait PragmaExtension: ConnectionExtension {
Ok(())
}
fn pragma_ret<ST, T, D: std::fmt::Display>(
&self,
key: &str,
val: D,
schema: Option<&str>,
) -> Result<T>
fn pragma_ret<ST, T, D: std::fmt::Display>(&self, key: &str, val: D, schema: Option<&str>) -> Result<T>
where
SqlLiteral<ST>: LoadQuery<SqliteConnection, T>,
{
@ -57,36 +52,22 @@ pub trait PragmaExtension: ConnectionExtension {
self.pragma_ret::<Integer, i32, i32>("busy_timeout", timeout_ms, None)
}
fn pragma_get_busy_timeout(&self) -> Result<i32> {
self.pragma_get::<Integer, i32>("busy_timeout", None)
}
fn pragma_get_busy_timeout(&self) -> Result<i32> { self.pragma_get::<Integer, i32>("busy_timeout", None) }
fn pragma_set_journal_mode(
&self,
mode: SQLiteJournalMode,
schema: Option<&str>,
) -> Result<i32> {
fn pragma_set_journal_mode(&self, mode: SQLiteJournalMode, schema: Option<&str>) -> Result<i32> {
self.pragma_ret::<Integer, i32, SQLiteJournalMode>("journal_mode", mode, schema)
}
fn pragma_get_journal_mode(&self, schema: Option<&str>) -> Result<SQLiteJournalMode> {
Ok(self
.pragma_get::<Text, String>("journal_mode", schema)?
.parse()?)
Ok(self.pragma_get::<Text, String>("journal_mode", schema)?.parse()?)
}
fn pragma_set_synchronous(
&self,
synchronous: SQLiteSynchronous,
schema: Option<&str>,
) -> Result<()> {
fn pragma_set_synchronous(&self, synchronous: SQLiteSynchronous, schema: Option<&str>) -> Result<()> {
self.pragma("synchronous", synchronous as u8, schema)
}
fn pragma_get_synchronous(&self, schema: Option<&str>) -> Result<SQLiteSynchronous> {
Ok(self
.pragma_get::<Integer, i32>("synchronous", schema)?
.try_into()?)
Ok(self.pragma_get::<Integer, i32>("synchronous", schema)?.try_into()?)
}
}
impl PragmaExtension for SqliteConnection {}

View File

@ -57,7 +57,5 @@ mod tests {
}
#[quickcheck_macros::quickcheck]
fn valid_emails_are_parsed_successfully(valid_email: ValidEmailFixture) -> bool {
UserEmail::parse(valid_email.0).is_ok()
}
fn valid_emails_are_parsed_successfully(valid_email: ValidEmailFixture) -> bool { UserEmail::parse(valid_email.0).is_ok() }
}

View File

@ -3,10 +3,7 @@ use derive_more::Display;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_dispatch::prelude::{EventResponse, ResponseBuilder};
use std::{
convert::TryInto,
fmt::{Debug, Formatter},
};
use std::{convert::TryInto, fmt::Debug};
#[derive(Debug, Default, Clone, ProtoBuf)]
pub struct UserError {

View File

@ -1,4 +1,2 @@
mod model;
pub use model::*;

View File

@ -1,19 +1,19 @@
// Auto-generated, do not edit
// Auto-generated, do not edit
mod observable;
pub use observable::*;
mod observable;
pub use observable::*;
mod user_table;
pub use user_table::*;
mod user_table;
pub use user_table::*;
mod errors;
pub use errors::*;
mod errors;
pub use errors::*;
mod user_profile;
pub use user_profile::*;
mod user_profile;
pub use user_profile::*;
mod event;
pub use event::*;
mod event;
pub use event::*;
mod auth;
pub use auth::*;
mod auth;
pub use auth::*;

View File

@ -22,11 +22,7 @@ impl TryInto<DeleteWorkspaceParams> for DeleteWorkspaceRequest {
fn try_into(self) -> Result<DeleteWorkspaceParams, Self::Error> {
let workspace_id = WorkspaceId::parse(self.workspace_id)
.map_err(|e| {
ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid)
.msg(e)
.build()
})?
.map_err(|e| ErrorBuilder::new(ErrorCode::WorkspaceIdInvalid).msg(e).build())?
.0;
Ok(DeleteWorkspaceParams { workspace_id })

View File

@ -54,6 +54,15 @@ pub(crate) async fn update_view_handler(
Ok(())
}
#[tracing::instrument(skip(data, controller), err)]
pub(crate) async fn update_view_data_handler(
data: Data<UpdateViewDataRequest>,
controller: Unit<Arc<ViewController>>,
) -> Result<(), WorkspaceError> {
let params: UpdateDocParams = data.into_inner().try_into()?;
let _ = controller.update_view_data(params).await?;
Ok(())
}
#[tracing::instrument(skip(data, controller), err)]
pub(crate) async fn delete_view_handler(
@ -74,13 +83,3 @@ pub(crate) async fn open_view_handler(
let doc = controller.open_view(params).await?;
data_result(doc)
}
#[tracing::instrument(skip(data, controller), err)]
pub(crate) async fn update_view_data_handler(
data: Data<UpdateViewDataRequest>,
controller: Unit<Arc<ViewController>>,
) -> Result<(), WorkspaceError> {
let params: UpdateDocParams = data.into_inner().try_into()?;
let _ = controller.update_view_data(params).await?;
Ok(())
}

View File

@ -1,15 +1,13 @@
#[macro_export]
macro_rules! impl_sql_binary_expression {
($target:ident) => {
impl diesel::serialize::ToSql<diesel::sql_types::Binary, diesel::sqlite::Sqlite>
for $target
{
impl diesel::serialize::ToSql<diesel::sql_types::Binary, diesel::sqlite::Sqlite> for $target {
fn to_sql<W: std::io::Write>(
&self,
out: &mut diesel::serialize::Output<W, diesel::sqlite::Sqlite>,
) -> diesel::serialize::Result {
let bytes: Vec<u8> = self.try_into().map_err(|e| format!("{:?}", e))?;
diesel::serialize::ToSql::<diesel::sql_types::Binary,diesel::sqlite::Sqlite,>::to_sql(&bytes, out)
diesel::serialize::ToSql::<diesel::sql_types::Binary, diesel::sqlite::Sqlite>::to_sql(&bytes, out)
}
}
// https://docs.diesel.rs/src/diesel/sqlite/types/mod.rs.html#30-33
@ -25,20 +23,13 @@ macro_rules! impl_sql_binary_expression {
*const [u8]: diesel::deserialize::FromSql<diesel::sql_types::Binary, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
let slice_ptr = <*const [u8] as diesel::deserialize::FromSql<
diesel::sql_types::Binary,
DB,
>>::from_sql(bytes)?;
let slice_ptr = <*const [u8] as diesel::deserialize::FromSql<diesel::sql_types::Binary, DB>>::from_sql(bytes)?;
let bytes = unsafe { &*slice_ptr };
match $target::try_from(bytes) {
Ok(object) => Ok(object),
Err(e) => {
log::error!(
"{:?} deserialize from bytes fail. {:?}",
std::any::type_name::<$target>(),
e
);
log::error!("{:?} deserialize from bytes fail. {:?}", std::any::type_name::<$target>(), e);
panic!();
},
}
@ -63,9 +54,7 @@ macro_rules! impl_sql_integer_expression {
DB: diesel::backend::Backend,
i32: ToSql<Integer, DB>,
{
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
(*self as i32).to_sql(out)
}
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result { (*self as i32).to_sql(out) }
}
impl<DB> FromSql<Integer, DB> for $target
@ -105,9 +94,7 @@ macro_rules! impl_def_and_def_mut {
impl $target {
#[allow(dead_code)]
pub fn take_items(&mut self) -> Vec<$item> {
::std::mem::replace(&mut self.items, vec![])
}
pub fn take_items(&mut self) -> Vec<$item> { ::std::mem::replace(&mut self.items, vec![]) }
#[allow(dead_code)]
pub fn push(&mut self, item: $item) {

View File

@ -1,4 +1,2 @@
mod model;
pub use model::*;

View File

@ -1,49 +1,49 @@
// Auto-generated, do not edit
// Auto-generated, do not edit
mod view_update;
pub use view_update::*;
mod view_update;
pub use view_update::*;
mod view_delete;
pub use view_delete::*;
mod view_delete;
pub use view_delete::*;
mod app_query;
pub use app_query::*;
mod app_query;
pub use app_query::*;
mod workspace_delete;
pub use workspace_delete::*;
mod workspace_delete;
pub use workspace_delete::*;
mod observable;
pub use observable::*;
mod observable;
pub use observable::*;
mod errors;
pub use errors::*;
mod errors;
pub use errors::*;
mod workspace_update;
pub use workspace_update::*;
mod workspace_update;
pub use workspace_update::*;
mod app_create;
pub use app_create::*;
mod app_create;
pub use app_create::*;
mod workspace_query;
pub use workspace_query::*;
mod workspace_query;
pub use workspace_query::*;
mod event;
pub use event::*;
mod event;
pub use event::*;
mod view_create;
pub use view_create::*;
mod view_create;
pub use view_create::*;
mod workspace_user_detail;
pub use workspace_user_detail::*;
mod workspace_user_detail;
pub use workspace_user_detail::*;
mod workspace_create;
pub use workspace_create::*;
mod workspace_create;
pub use workspace_create::*;
mod app_update;
pub use app_update::*;
mod app_update;
pub use app_update::*;
mod view_query;
pub use view_query::*;
mod view_query;
pub use view_query::*;
mod app_delete;
pub use app_delete::*;
mod app_delete;
pub use app_delete::*;

View File

@ -149,7 +149,7 @@ impl AppController {
match server.read_app(&token, params).await {
Ok(option) => match option {
None => {},
Some(app) => {},
Some(_app) => {},
},
Err(_) => {},
}

View File

@ -114,7 +114,7 @@ pub fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) -> Opt
.sync_send()
.parse::<RepeatedWorkspace>();
let mut workspaces = vec![];
let mut workspaces;
if let Some(workspace_id) = &request.workspace_id {
workspaces = repeated_workspace
.take_items()