Skip to content

Commit aca9b81

Browse files
committed
chore: implement folder
1 parent 81dd353 commit aca9b81

File tree

10 files changed

+243
-128
lines changed

10 files changed

+243
-128
lines changed

shared-lib/flowy-ast/src/ast.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ pub struct ASTField<'a> {
123123
pub node_attrs: NodeStructAttrs,
124124
pub ty: &'a syn::Type,
125125
pub original: &'a syn::Field,
126+
// If the field is Vec<String>, then the bracket_ty will be Vec
126127
pub bracket_ty: Option<syn::Ident>,
128+
// If the field is Vec<String>, then the bracket_inner_ty will be String
127129
pub bracket_inner_ty: Option<syn::Ident>,
128130
pub bracket_category: Option<BracketCategory>,
129131
}

shared-lib/flowy-ast/src/node_attrs.rs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,19 @@ use syn::{
1111

1212
pub struct NodeStructAttrs {
1313
pub rename: Option<LitStr>,
14-
pub is_children: bool,
15-
node_index: Option<syn::LitInt>,
14+
pub has_child: bool,
15+
pub child_name: Option<LitStr>,
16+
pub child_index: Option<syn::LitInt>,
1617
get_node_value_with: Option<syn::ExprPath>,
1718
set_node_value_with: Option<syn::ExprPath>,
1819
}
1920

2021
impl NodeStructAttrs {
2122
/// Extract out the `#[node(...)]` attributes from a struct field.
2223
pub fn from_ast(ast_result: &ASTResult, index: usize, field: &syn::Field) -> Self {
23-
let mut node_index = ASTAttr::none(ast_result, NODE_INDEX);
24-
let mut rename = ASTAttr::none(ast_result, NODE_RENAME);
25-
let mut is_children = ASTAttr::none(ast_result, NODE_CHILDREN);
24+
let mut rename = ASTAttr::none(ast_result, RENAME_NODE);
25+
let mut child_name = ASTAttr::none(ast_result, CHILD_NODE_NAME);
26+
let mut child_index = ASTAttr::none(ast_result, CHILD_NODE_INDEX);
2627
let mut get_node_value_with = ASTAttr::none(ast_result, GET_NODE_VALUE_WITH);
2728
let mut set_node_value_with = ASTAttr::none(ast_result, SET_NODE_VALUE_WITH);
2829

@@ -33,25 +34,27 @@ impl NodeStructAttrs {
3334
.flatten()
3435
{
3536
match &meta_item {
36-
// Parse '#[node(index = x)]'
37-
Meta(NameValue(m)) if m.path == NODE_INDEX => {
38-
if let syn::Lit::Int(lit) = &m.lit {
39-
node_index.set(&m.path, lit.clone());
37+
// Parse '#[node(rename = x)]'
38+
Meta(NameValue(m)) if m.path == RENAME_NODE => {
39+
if let syn::Lit::Str(lit) = &m.lit {
40+
rename.set(&m.path, lit.clone());
4041
}
4142
}
4243

43-
// Parse '#[node(children)]'
44-
Meta(Path(path)) if path == NODE_CHILDREN => {
45-
eprintln!("😄 {:?}", path);
46-
is_children.set(path, true);
44+
// Parse '#[node(child_name = x)]'
45+
Meta(NameValue(m)) if m.path == CHILD_NODE_NAME => {
46+
if let syn::Lit::Str(lit) = &m.lit {
47+
child_name.set(&m.path, lit.clone());
48+
}
4749
}
4850

49-
// Parse '#[node(rename = x)]'
50-
Meta(NameValue(m)) if m.path == NODE_RENAME => {
51-
if let syn::Lit::Str(lit) = &m.lit {
52-
rename.set(&m.path, lit.clone());
51+
// Parse '#[node(child_index = x)]'
52+
Meta(NameValue(m)) if m.path == CHILD_NODE_INDEX => {
53+
if let syn::Lit::Int(lit) = &m.lit {
54+
child_index.set(&m.path, lit.clone());
5355
}
5456
}
57+
5558
// Parse `#[node(get_node_value_with = "...")]`
5659
Meta(NameValue(m)) if m.path == GET_NODE_VALUE_WITH => {
5760
if let Ok(path) = parse_lit_into_expr_path(ast_result, GET_NODE_VALUE_WITH, &m.lit) {
@@ -76,11 +79,12 @@ impl NodeStructAttrs {
7679
}
7780
}
7881
}
79-
82+
let child_name = child_name.get();
8083
NodeStructAttrs {
8184
rename: rename.get(),
82-
node_index: node_index.get(),
83-
is_children: is_children.get().unwrap_or(false),
85+
child_index: child_index.get(),
86+
has_child: child_name.is_some(),
87+
child_name,
8488
get_node_value_with: get_node_value_with.get(),
8589
set_node_value_with: set_node_value_with.get(),
8690
}

shared-lib/flowy-ast/src/symbol.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ pub const NODE_ATTRS: Symbol = Symbol("node");
3737
pub const NODES_ATTRS: Symbol = Symbol("nodes");
3838
pub const NODE_TYPE: Symbol = Symbol("node_type");
3939
pub const NODE_INDEX: Symbol = Symbol("index");
40-
pub const NODE_RENAME: Symbol = Symbol("rename");
41-
pub const NODE_CHILDREN: Symbol = Symbol("children");
40+
pub const RENAME_NODE: Symbol = Symbol("rename");
41+
pub const CHILD_NODE_NAME: Symbol = Symbol("child_name");
42+
pub const CHILD_NODE_INDEX: Symbol = Symbol("child_index");
4243
pub const SKIP_NODE_ATTRS: Symbol = Symbol("skip_node_attribute");
4344
pub const GET_NODE_VALUE_WITH: Symbol = Symbol("get_value_with");
4445
pub const SET_NODE_VALUE_WITH: Symbol = Symbol("set_value_with");

shared-lib/flowy-derive/src/node/mod.rs

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,98 @@ pub fn expand_derive(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::E
99
};
1010

1111
let mut token_stream: TokenStream = TokenStream::default();
12+
token_stream.extend(make_helper_funcs_token_stream(&cont));
1213
token_stream.extend(make_to_node_data_token_stream(&cont));
1314

1415
if let Some(get_value_token_stream) = make_get_set_value_token_steam(&cont) {
1516
token_stream.extend(get_value_token_stream);
1617
}
1718

19+
token_stream.extend(make_alter_children_token_stream(&ast_result, &cont));
1820
ast_result.check()?;
1921
Ok(token_stream)
2022
}
2123

22-
pub fn make_alter_children_token_stream(ast: &ASTContainer) -> TokenStream {
24+
pub fn make_helper_funcs_token_stream(ast: &ASTContainer) -> TokenStream {
2325
let mut token_streams = TokenStream::default();
26+
let struct_ident = &ast.ident;
27+
token_streams.extend(quote! {
28+
impl #struct_ident {
29+
pub fn get_path(&self) -> Path {
30+
self.tree.read().path_from_node_id(self.node_id.clone())
31+
}
32+
}
33+
});
34+
token_streams
35+
}
36+
37+
pub fn make_alter_children_token_stream(ast_result: &ASTResult, ast: &ASTContainer) -> TokenStream {
38+
let mut token_streams = TokenStream::default();
39+
let children_fields = ast
40+
.data
41+
.all_fields()
42+
.filter(|field| field.node_attrs.has_child)
43+
.collect::<Vec<&ASTField>>();
44+
45+
if !children_fields.is_empty() {
46+
let struct_ident = &ast.ident;
47+
if children_fields.len() > 1 {
48+
ast_result.error_spanned_by(struct_ident, "Only one children property");
49+
return token_streams;
50+
}
51+
let children_field = children_fields.first().unwrap();
52+
let field_name = children_field.name().unwrap();
53+
eprintln!("😄 {:?} {:?}", struct_ident, field_name);
54+
let child_name = children_field.node_attrs.child_name.as_ref().unwrap();
55+
let get_func_name = format_ident!("get_{}", child_name.value());
56+
let get_mut_func_name = format_ident!("get_mut_{}", child_name.value());
57+
let add_func_name = format_ident!("add_{}", child_name.value());
58+
let remove_func_name = format_ident!("remove_{}", child_name.value());
59+
let ty = children_field.bracket_inner_ty.as_ref().unwrap().clone();
60+
61+
token_streams.extend(quote! {
62+
impl #struct_ident {
63+
pub fn #get_func_name(&self, id: &str) -> Option<&#ty> {
64+
self.#field_name.iter().find(|element| element.id == id)
65+
}
66+
67+
pub fn #get_mut_func_name(&mut self, id: &str) -> Option<&mut #ty> {
68+
self.#field_name.iter_mut().find(|element| element.id == id)
69+
}
70+
71+
pub fn #remove_func_name(&mut self, id: &str) {
72+
if let Some(index) = self.#field_name.iter().position(|element| element.id == id) {
73+
let element = self.#field_name.remove(index);
74+
let element_path = element.get_path();
75+
76+
let mut write_guard = self.tree.write();
77+
let mut nodes = vec![];
78+
if let Some(node_data) = write_guard.get_node_data(element.node_id.clone()) {
79+
nodes.push(node_data);
80+
}
81+
let _ = write_guard.apply_op(NodeOperation::Delete {
82+
path: element_path,
83+
nodes,
84+
});
85+
}
86+
}
87+
88+
pub fn #add_func_name(&mut self, value: #ty) {
89+
let mut transaction = Transaction::new();
90+
let parent_path = self.get_path();
91+
let path = parent_path.clone_with(self.#field_name.len());
92+
let node_data = value.to_node_data();
93+
transaction.push_operation(NodeOperation::Insert {
94+
path,
95+
nodes: vec![node_data],
96+
});
97+
98+
let _ = self.tree.write().apply_transaction(transaction);
99+
self.#field_name.push(value);
100+
}
101+
}
102+
});
103+
}
24104

25105
token_streams
26106
}
@@ -35,7 +115,7 @@ pub fn make_to_node_data_token_stream(ast: &ASTContainer) -> TokenStream {
35115
let set_key_values = ast
36116
.data
37117
.all_fields()
38-
.filter(|field| !field.node_attrs.is_children)
118+
.filter(|field| !field.node_attrs.has_child)
39119
.flat_map(|field| {
40120
let mut field_name = field.name().expect("the name of the field should not be empty");
41121
let original_field_name = field.name().expect("the name of the field should not be empty");
@@ -51,7 +131,7 @@ pub fn make_to_node_data_token_stream(ast: &ASTContainer) -> TokenStream {
51131
let children_fields = ast
52132
.data
53133
.all_fields()
54-
.filter(|field| field.node_attrs.is_children)
134+
.filter(|field| field.node_attrs.has_child)
55135
.collect::<Vec<&ASTField>>();
56136

57137
let childrens_token_streams = match children_fields.is_empty() {
@@ -72,8 +152,8 @@ pub fn make_to_node_data_token_stream(ast: &ASTContainer) -> TokenStream {
72152
};
73153

74154
token_streams.extend(quote! {
75-
impl #struct_ident {
76-
pub fn to_node_data(&self) -> NodeData {
155+
impl ToNodeData for #struct_ident {
156+
fn to_node_data(&self) -> NodeData {
77157
#childrens_token_streams
78158

79159
let builder = NodeDataBuilder::new(#node_type)
@@ -94,7 +174,7 @@ pub fn make_get_set_value_token_steam(ast: &ASTContainer) -> Option<TokenStream>
94174

95175
let tree = format_ident!("tree");
96176
for field in ast.data.all_fields() {
97-
if field.node_attrs.is_children {
177+
if field.node_attrs.has_child {
98178
continue;
99179
}
100180

@@ -113,7 +193,7 @@ pub fn make_get_set_value_token_steam(ast: &ASTContainer) -> Option<TokenStream>
113193
token_streams.extend(quote! {
114194
impl #struct_ident {
115195
pub fn #get_func_name(&self) -> Option<#get_value_return_ty> {
116-
#get_value_with_fn(self.#tree.clone(), &self.path, #field_name_str)
196+
#get_value_with_fn(self.#tree.clone(), &self.node_id, #field_name_str)
117197
}
118198
}
119199
});
@@ -123,12 +203,11 @@ pub fn make_get_set_value_token_steam(ast: &ASTContainer) -> Option<TokenStream>
123203
token_streams.extend(quote! {
124204
impl #struct_ident {
125205
pub fn #set_func_name(&self, value: #set_value_input_ty) {
126-
let _ = #set_value_with_fn(self.#tree.clone(), &self.path, #field_name_str, value);
206+
let _ = #set_value_with_fn(self.#tree.clone(), &self.node_id, #field_name_str, value);
127207
}
128208
}
129209
});
130210
}
131211
}
132-
ast.data.all_fields().for_each(|field| {});
133212
Some(token_streams)
134213
}

shared-lib/flowy-sync/src/client_folder/folder_node.rs

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,42 +11,6 @@ use std::sync::Arc;
1111

1212
pub type AtomicNodeTree = RwLock<NodeTree>;
1313

14-
// pub struct FolderNodePad2 {
15-
// tree: Arc<AtomicNodeTree>,
16-
//
17-
// #[node(rename = "workspaces", revision = "WorkspaceRevision")]
18-
// workspaces: Vec<Arc<WorkspaceNode>>,
19-
// }
20-
//
21-
// impl FolderNodePad2 {
22-
// pub fn get_workspace() {}
23-
// pub fn get_mut_workspace() {}
24-
// pub fn add_workspace() {}
25-
// pub fn remove_workspace() {}
26-
// pub fn to_json() {}
27-
// }
28-
//
29-
// #[derive(Debug, Clone)]
30-
// pub struct WorkspaceNode2 {
31-
// tree: Arc<AtomicNodeTree>,
32-
// pub id: String,
33-
// pub name: String,
34-
// pub path: Path,
35-
// }
36-
//
37-
// impl WorkspaceNode2 {
38-
// pub fn get_id() {}
39-
// pub fn set_id() {}
40-
// pub fn get_name() {}
41-
// pub fn set_name() {}
42-
// pub fn get_apps() {}
43-
//
44-
// pub fn get_app() {}
45-
// pub fn get_mut_app() {}
46-
// pub fn add_app() {}
47-
// pub fn remove_app() {}
48-
// }
49-
5014
pub struct FolderNodePad {
5115
tree: Arc<AtomicNodeTree>,
5216
// name: workspaces, index of the node,
@@ -71,31 +35,29 @@ impl FolderNodePad {
7135

7236
pub fn remove_workspace(&mut self, workspace_id: &str) {
7337
if let Some(workspace) = self.workspaces.iter().find(|workspace| workspace.id == workspace_id) {
38+
let mut write_guard = self.tree.write();
7439
let mut nodes = vec![];
75-
let workspace_node = self.tree.read().get_node_data_at_path(&workspace.path);
76-
debug_assert!(workspace_node.is_some());
7740

78-
if let Some(node_data) = workspace_node {
41+
if let Some(node_data) = write_guard.get_node_data_at_path(&workspace.path) {
7942
nodes.push(node_data);
8043
}
81-
let delete_operation = NodeOperation::Delete {
44+
let _ = write_guard.apply_op(NodeOperation::Delete {
8245
path: workspace.path.clone(),
8346
nodes,
84-
};
85-
let _ = self.tree.write().apply_op(delete_operation);
47+
});
8648
}
8749
}
8850

8951
pub fn add_workspace(&mut self, revision: WorkspaceRevision) -> CollaborateResult<()> {
9052
let mut transaction = Transaction::new();
91-
let workspace_node = WorkspaceNode::from_workspace_revision(
53+
let node = WorkspaceNode::from_workspace_revision(
9254
&mut transaction,
9355
revision,
9456
self.tree.clone(),
9557
workspaces_path().clone_with(self.workspaces.len()),
9658
)?;
9759
let _ = self.tree.write().apply_transaction(transaction)?;
98-
self.workspaces.push(Arc::new(workspace_node));
60+
self.workspaces.push(Arc::new(node));
9961
Ok(())
10062
}
10163

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use crate::client_folder::workspace_node_2::WorkspaceNode2;
2+
use crate::errors::{CollaborateError, CollaborateResult};
3+
use flowy_derive::Node;
4+
use lib_ot::core::NodeTree;
5+
use lib_ot::core::*;
6+
use parking_lot::RwLock;
7+
use std::sync::Arc;
8+
9+
pub type AtomicNodeTree = RwLock<NodeTree>;
10+
11+
#[derive(Node)]
12+
#[node_type = "folder"]
13+
pub struct FolderNodePad2 {
14+
tree: Arc<AtomicNodeTree>,
15+
node_id: NodeId,
16+
// name: workspaces, index of the node,
17+
#[node(child_name = "child")]
18+
children: Vec<Box<dyn ToNodeData>>,
19+
}
20+
21+
impl FolderNodePad2 {
22+
pub fn new() -> Self {
23+
// let workspace_node = NodeDataBuilder::new("workspaces").build();
24+
// let trash_node = NodeDataBuilder::new("trash").build();
25+
// let folder_node = NodeDataBuilder::new("folder")
26+
// .add_node_data(workspace_node)
27+
// .add_node_data(trash_node)
28+
// .build();
29+
//
30+
// let operation = NodeOperation::Insert {
31+
// path: folder_path(),
32+
// nodes: vec![folder_node],
33+
// };
34+
// let mut tree = NodeTree::default();
35+
// let _ = tree.apply_op(operation).unwrap();
36+
//
37+
// Self {
38+
// tree: Arc::new(RwLock::new(tree)),
39+
// workspaces: vec![],
40+
// trash: vec![],
41+
// }
42+
todo!()
43+
}
44+
45+
pub fn to_json(&self, pretty: bool) -> CollaborateResult<String> {
46+
self.tree
47+
.read()
48+
.to_json(pretty)
49+
.map_err(|e| CollaborateError::serde().context(e))
50+
}
51+
}

0 commit comments

Comments
 (0)