mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: deps crates (#4362)
* refactor: rename flowy-folder-deps to flowy-folder-pub * chore: rename crates * chore: move flowy-task to lib-infra * chore: rename crates * refactor: user manager dir
This commit is contained in:
17
frontend/rust-lib/flowy-folder-pub/Cargo.toml
Normal file
17
frontend/rust-lib/flowy-folder-pub/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "flowy-folder-pub"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
lib-infra = { workspace = true }
|
||||
collab-folder = { version = "0.1.0" }
|
||||
collab = { version = "0.1.0" }
|
||||
collab-entity = { version = "0.1.0" }
|
||||
uuid.workspace = true
|
||||
anyhow.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tokio.workspace = true
|
80
frontend/rust-lib/flowy-folder-pub/src/cloud.rs
Normal file
80
frontend/rust-lib/flowy-folder-pub/src/cloud.rs
Normal file
@ -0,0 +1,80 @@
|
||||
pub use anyhow::Error;
|
||||
use collab::core::collab::CollabDocState;
|
||||
use collab_entity::CollabType;
|
||||
pub use collab_folder::{Folder, FolderData, Workspace};
|
||||
use uuid::Uuid;
|
||||
|
||||
use lib_infra::future::FutureResult;
|
||||
|
||||
/// [FolderCloudService] represents the cloud service for folder.
|
||||
pub trait FolderCloudService: Send + Sync + 'static {
|
||||
/// Creates a new workspace for the user.
|
||||
/// Returns error if the cloud service doesn't support multiple workspaces
|
||||
fn create_workspace(&self, uid: i64, name: &str) -> FutureResult<Workspace, Error>;
|
||||
|
||||
fn open_workspace(&self, workspace_id: &str) -> FutureResult<(), Error>;
|
||||
|
||||
/// Returns all workspaces of the user.
|
||||
/// Returns vec![] if the cloud service doesn't support multiple workspaces
|
||||
fn get_all_workspace(&self) -> FutureResult<Vec<WorkspaceRecord>, Error>;
|
||||
|
||||
fn get_folder_data(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
uid: &i64,
|
||||
) -> FutureResult<Option<FolderData>, Error>;
|
||||
|
||||
fn get_folder_snapshots(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
limit: usize,
|
||||
) -> FutureResult<Vec<FolderSnapshot>, Error>;
|
||||
|
||||
/// The suffix 'f' in the method name serves as a workaround to avoid naming conflicts with the existing method `get_collab_doc_state`.
|
||||
fn get_collab_doc_state_f(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
uid: i64,
|
||||
collab_type: CollabType,
|
||||
object_id: &str,
|
||||
) -> FutureResult<CollabDocState, Error>;
|
||||
|
||||
/// The suffix 'f' in the method name serves as a workaround to avoid naming conflicts with the existing method `get_collab_doc_state`.
|
||||
fn batch_create_collab_object_f(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
objects: Vec<FolderCollabParams>,
|
||||
) -> FutureResult<(), Error>;
|
||||
|
||||
fn service_name(&self) -> String;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FolderCollabParams {
|
||||
pub object_id: String,
|
||||
pub encoded_collab_v1: Vec<u8>,
|
||||
pub collab_type: CollabType,
|
||||
pub override_if_exist: bool,
|
||||
}
|
||||
|
||||
pub struct FolderSnapshot {
|
||||
pub snapshot_id: i64,
|
||||
pub database_id: String,
|
||||
pub data: Vec<u8>,
|
||||
pub created_at: i64,
|
||||
}
|
||||
|
||||
pub fn gen_workspace_id() -> Uuid {
|
||||
uuid::Uuid::new_v4()
|
||||
}
|
||||
|
||||
pub fn gen_view_id() -> Uuid {
|
||||
uuid::Uuid::new_v4()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WorkspaceRecord {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub created_at: i64,
|
||||
}
|
19
frontend/rust-lib/flowy-folder-pub/src/entities.rs
Normal file
19
frontend/rust-lib/flowy-folder-pub/src/entities.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use crate::folder_builder::ParentChildViews;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub enum ImportData {
|
||||
AppFlowyDataFolder {
|
||||
views: Vec<ParentChildViews>,
|
||||
/// Used to update the [DatabaseViewTrackerList] when importing the database.
|
||||
database_view_ids_by_database_id: HashMap<String, Vec<String>>,
|
||||
row_object_ids: Vec<String>,
|
||||
document_object_ids: Vec<String>,
|
||||
database_object_ids: Vec<String>,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct ImportViews {
|
||||
pub views: Vec<ParentChildViews>,
|
||||
/// Used to update the [DatabaseViewTrackerList] when importing the database.
|
||||
pub database_view_ids_by_database_id: HashMap<String, Vec<String>>,
|
||||
}
|
317
frontend/rust-lib/flowy-folder-pub/src/folder_builder.rs
Normal file
317
frontend/rust-lib/flowy-folder-pub/src/folder_builder.rs
Normal file
@ -0,0 +1,317 @@
|
||||
use crate::cloud::gen_view_id;
|
||||
use collab_folder::{RepeatedViewIdentifier, View, ViewIcon, ViewIdentifier, ViewLayout};
|
||||
use lib_infra::util::timestamp;
|
||||
use std::future::Future;
|
||||
|
||||
/// A builder for creating a view for a workspace.
|
||||
/// The views created by this builder will be the first level views of the workspace.
|
||||
pub struct WorkspaceViewBuilder {
|
||||
pub uid: i64,
|
||||
pub workspace_id: String,
|
||||
pub views: Vec<ParentChildViews>,
|
||||
}
|
||||
|
||||
impl WorkspaceViewBuilder {
|
||||
pub fn new(workspace_id: String, uid: i64) -> Self {
|
||||
Self {
|
||||
uid,
|
||||
workspace_id,
|
||||
views: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn with_view_builder<F, O>(&mut self, view_builder: F)
|
||||
where
|
||||
F: Fn(ViewBuilder) -> O,
|
||||
O: Future<Output = ParentChildViews>,
|
||||
{
|
||||
let builder = ViewBuilder::new(self.uid, self.workspace_id.clone());
|
||||
self.views.push(view_builder(builder).await);
|
||||
}
|
||||
|
||||
pub fn build(&mut self) -> Vec<ParentChildViews> {
|
||||
std::mem::take(&mut self.views)
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder for creating a view.
|
||||
/// The default layout of the view is [ViewLayout::Document]
|
||||
pub struct ViewBuilder {
|
||||
uid: i64,
|
||||
parent_view_id: String,
|
||||
view_id: String,
|
||||
name: String,
|
||||
desc: String,
|
||||
layout: ViewLayout,
|
||||
child_views: Vec<ParentChildViews>,
|
||||
is_favorite: bool,
|
||||
icon: Option<ViewIcon>,
|
||||
}
|
||||
|
||||
impl ViewBuilder {
|
||||
pub fn new(uid: i64, parent_view_id: String) -> Self {
|
||||
Self {
|
||||
uid,
|
||||
parent_view_id,
|
||||
view_id: gen_view_id().to_string(),
|
||||
name: Default::default(),
|
||||
desc: Default::default(),
|
||||
layout: ViewLayout::Document,
|
||||
child_views: vec![],
|
||||
is_favorite: false,
|
||||
icon: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view_id(&self) -> &str {
|
||||
&self.view_id
|
||||
}
|
||||
|
||||
pub fn with_view_id<T: ToString>(mut self, view_id: T) -> Self {
|
||||
self.view_id = view_id.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_layout(mut self, layout: ViewLayout) -> Self {
|
||||
self.layout = layout;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_name<T: ToString>(mut self, name: T) -> Self {
|
||||
self.name = name.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_desc(mut self, desc: &str) -> Self {
|
||||
self.desc = desc.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_icon(mut self, icon: &str) -> Self {
|
||||
self.icon = Some(ViewIcon {
|
||||
ty: collab_folder::IconType::Emoji,
|
||||
value: icon.to_string(),
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_view(mut self, view: ParentChildViews) -> Self {
|
||||
self.child_views.push(view);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_child_views(mut self, mut views: Vec<ParentChildViews>) -> Self {
|
||||
self.child_views.append(&mut views);
|
||||
self
|
||||
}
|
||||
|
||||
/// Create a child view for the current view.
|
||||
/// The view created by this builder will be the next level view of the current view.
|
||||
pub async fn with_child_view_builder<F, O>(mut self, child_view_builder: F) -> Self
|
||||
where
|
||||
F: Fn(ViewBuilder) -> O,
|
||||
O: Future<Output = ParentChildViews>,
|
||||
{
|
||||
let builder = ViewBuilder::new(self.uid, self.view_id.clone());
|
||||
self.child_views.push(child_view_builder(builder).await);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> ParentChildViews {
|
||||
let view = View {
|
||||
id: self.view_id,
|
||||
parent_view_id: self.parent_view_id,
|
||||
name: self.name,
|
||||
desc: self.desc,
|
||||
created_at: timestamp(),
|
||||
is_favorite: self.is_favorite,
|
||||
layout: self.layout,
|
||||
icon: self.icon,
|
||||
created_by: Some(self.uid),
|
||||
last_edited_time: 0,
|
||||
children: RepeatedViewIdentifier::new(
|
||||
self
|
||||
.child_views
|
||||
.iter()
|
||||
.map(|v| ViewIdentifier {
|
||||
id: v.parent_view.id.clone(),
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
last_edited_by: Some(self.uid),
|
||||
};
|
||||
ParentChildViews {
|
||||
parent_view: view,
|
||||
child_views: self.child_views,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ParentChildViews {
|
||||
pub parent_view: View,
|
||||
pub child_views: Vec<ParentChildViews>,
|
||||
}
|
||||
|
||||
impl ParentChildViews {
|
||||
pub fn new(view: View) -> Self {
|
||||
Self {
|
||||
parent_view: view,
|
||||
child_views: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flatten(self) -> Vec<View> {
|
||||
FlattedViews::flatten_views(vec![self])
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FlattedViews;
|
||||
|
||||
impl FlattedViews {
|
||||
pub fn flatten_views(views: Vec<ParentChildViews>) -> Vec<View> {
|
||||
let mut result = vec![];
|
||||
for view in views {
|
||||
result.push(view.parent_view);
|
||||
result.append(&mut Self::flatten_views(view.child_views));
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::folder_builder::{FlattedViews, WorkspaceViewBuilder};
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_first_level_views_test() {
|
||||
let workspace_id = "w1".to_string();
|
||||
let mut builder = WorkspaceViewBuilder::new(workspace_id, 1);
|
||||
builder
|
||||
.with_view_builder(|view_builder| async { view_builder.with_name("1").build() })
|
||||
.await;
|
||||
builder
|
||||
.with_view_builder(|view_builder| async { view_builder.with_name("2").build() })
|
||||
.await;
|
||||
builder
|
||||
.with_view_builder(|view_builder| async { view_builder.with_name("3").build() })
|
||||
.await;
|
||||
let workspace_views = builder.build();
|
||||
assert_eq!(workspace_views.len(), 3);
|
||||
|
||||
let views = FlattedViews::flatten_views(workspace_views);
|
||||
assert_eq!(views.len(), 3);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_view_with_child_views_test() {
|
||||
let workspace_id = "w1".to_string();
|
||||
let mut builder = WorkspaceViewBuilder::new(workspace_id, 1);
|
||||
builder
|
||||
.with_view_builder(|view_builder| async {
|
||||
view_builder
|
||||
.with_name("1")
|
||||
.with_child_view_builder(|child_view_builder| async {
|
||||
child_view_builder.with_name("1_1").build()
|
||||
})
|
||||
.await
|
||||
.with_child_view_builder(|child_view_builder| async {
|
||||
child_view_builder.with_name("1_2").build()
|
||||
})
|
||||
.await
|
||||
.build()
|
||||
})
|
||||
.await;
|
||||
builder
|
||||
.with_view_builder(|view_builder| async {
|
||||
view_builder
|
||||
.with_name("2")
|
||||
.with_child_view_builder(|child_view_builder| async {
|
||||
child_view_builder.with_name("2_1").build()
|
||||
})
|
||||
.await
|
||||
.build()
|
||||
})
|
||||
.await;
|
||||
let workspace_views = builder.build();
|
||||
assert_eq!(workspace_views.len(), 2);
|
||||
|
||||
assert_eq!(workspace_views[0].parent_view.name, "1");
|
||||
assert_eq!(workspace_views[0].child_views.len(), 2);
|
||||
assert_eq!(workspace_views[0].child_views[0].parent_view.name, "1_1");
|
||||
assert_eq!(workspace_views[0].child_views[1].parent_view.name, "1_2");
|
||||
assert_eq!(workspace_views[1].child_views.len(), 1);
|
||||
assert_eq!(workspace_views[1].child_views[0].parent_view.name, "2_1");
|
||||
|
||||
let views = FlattedViews::flatten_views(workspace_views);
|
||||
assert_eq!(views.len(), 5);
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn create_three_level_view_test() {
|
||||
let workspace_id = "w1".to_string();
|
||||
let mut builder = WorkspaceViewBuilder::new(workspace_id, 1);
|
||||
builder
|
||||
.with_view_builder(|view_builder| async {
|
||||
view_builder
|
||||
.with_name("1")
|
||||
.with_child_view_builder(|child_view_builder| async {
|
||||
child_view_builder
|
||||
.with_name("1_1")
|
||||
.with_child_view_builder(|b| async { b.with_name("1_1_1").build() })
|
||||
.await
|
||||
.with_child_view_builder(|b| async { b.with_name("1_1_2").build() })
|
||||
.await
|
||||
.build()
|
||||
})
|
||||
.await
|
||||
.with_child_view_builder(|child_view_builder| async {
|
||||
child_view_builder
|
||||
.with_name("1_2")
|
||||
.with_child_view_builder(|b| async { b.with_name("1_2_1").build() })
|
||||
.await
|
||||
.with_child_view_builder(|b| async { b.with_name("1_2_2").build() })
|
||||
.await
|
||||
.build()
|
||||
})
|
||||
.await
|
||||
.build()
|
||||
})
|
||||
.await;
|
||||
let workspace_views = builder.build();
|
||||
assert_eq!(workspace_views.len(), 1);
|
||||
|
||||
assert_eq!(workspace_views[0].parent_view.name, "1");
|
||||
assert_eq!(workspace_views[0].child_views.len(), 2);
|
||||
assert_eq!(workspace_views[0].child_views[0].parent_view.name, "1_1");
|
||||
assert_eq!(workspace_views[0].child_views[1].parent_view.name, "1_2");
|
||||
|
||||
assert_eq!(
|
||||
workspace_views[0].child_views[0].child_views[0]
|
||||
.parent_view
|
||||
.name,
|
||||
"1_1_1"
|
||||
);
|
||||
assert_eq!(
|
||||
workspace_views[0].child_views[0].child_views[1]
|
||||
.parent_view
|
||||
.name,
|
||||
"1_1_2"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
workspace_views[0].child_views[1].child_views[0]
|
||||
.parent_view
|
||||
.name,
|
||||
"1_2_1"
|
||||
);
|
||||
assert_eq!(
|
||||
workspace_views[0].child_views[1].child_views[1]
|
||||
.parent_view
|
||||
.name,
|
||||
"1_2_2"
|
||||
);
|
||||
|
||||
let views = FlattedViews::flatten_views(workspace_views);
|
||||
assert_eq!(views.len(), 7);
|
||||
}
|
||||
}
|
3
frontend/rust-lib/flowy-folder-pub/src/lib.rs
Normal file
3
frontend/rust-lib/flowy-folder-pub/src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub mod cloud;
|
||||
pub mod entities;
|
||||
pub mod folder_builder;
|
Reference in New Issue
Block a user