mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Refactor/selection option transform (#1294)
* chore: support unnamed struct in AST parser progress * chore: handle select option type option data transform in one place
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
mod multi_select_type_option;
|
mod multi_select_type_option;
|
||||||
mod select_type_option;
|
mod select_type_option;
|
||||||
mod single_select_type_option;
|
mod single_select_type_option;
|
||||||
|
mod type_option_transform;
|
||||||
|
|
||||||
pub use multi_select_type_option::*;
|
pub use multi_select_type_option::*;
|
||||||
pub use select_type_option::*;
|
pub use select_type_option::*;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::entities::FieldType;
|
use crate::entities::FieldType;
|
||||||
use crate::impl_type_option;
|
use crate::impl_type_option;
|
||||||
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
|
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
|
||||||
|
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformer;
|
||||||
use crate::services::field::type_options::util::get_cell_data;
|
use crate::services::field::type_options::util::get_cell_data;
|
||||||
use crate::services::field::{
|
use crate::services::field::{
|
||||||
BoxTypeOptionBuilder, SelectOptionCellChangeset, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction,
|
BoxTypeOptionBuilder, SelectOptionCellChangeset, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction,
|
||||||
@ -110,7 +111,7 @@ impl TypeOptionBuilder for MultiSelectTypeOptionBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transform(&mut self, field_type: &FieldType, type_option_data: String) {
|
fn transform(&mut self, field_type: &FieldType, type_option_data: String) {
|
||||||
self.0.transform_type_option(field_type, type_option_data);
|
SelectOptionTypeOptionTransformer::transform_type_option(&mut self.0, field_type, type_option_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -2,7 +2,8 @@ use crate::entities::{CellChangesetPB, FieldType, GridCellIdPB, GridCellIdParams
|
|||||||
use crate::services::cell::{
|
use crate::services::cell::{
|
||||||
CellBytes, CellBytesParser, CellData, CellDataIsEmpty, CellDisplayable, FromCellChangeset, FromCellString,
|
CellBytes, CellBytesParser, CellData, CellDataIsEmpty, CellDisplayable, FromCellChangeset, FromCellString,
|
||||||
};
|
};
|
||||||
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB, CHECK, UNCHECK};
|
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformer;
|
||||||
|
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||||
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
||||||
@ -119,25 +120,6 @@ pub trait SelectTypeOptionSharedAction: TypeOptionDataSerializer + Send + Sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_type_option(&mut self, field_type: &FieldType, _type_option_data: String) {
|
|
||||||
match field_type {
|
|
||||||
FieldType::Checkbox => {
|
|
||||||
//add Yes and No options if it does not exist.
|
|
||||||
if !self.options().iter().any(|option| option.name == CHECK) {
|
|
||||||
let check_option = SelectOptionPB::with_color(CHECK, SelectOptionColorPB::Green);
|
|
||||||
self.mut_options().push(check_option);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.options().iter().any(|option| option.name == UNCHECK) {
|
|
||||||
let uncheck_option = SelectOptionPB::with_color(UNCHECK, SelectOptionColorPB::Yellow);
|
|
||||||
self.mut_options().push(uncheck_option);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FieldType::MultiSelect => {}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform_cell_data(
|
fn transform_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: CellData<SelectOptionIds>,
|
cell_data: CellData<SelectOptionIds>,
|
||||||
@ -189,7 +171,12 @@ where
|
|||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
field_rev: &FieldRevision,
|
field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<CellBytes> {
|
) -> FlowyResult<CellBytes> {
|
||||||
self.transform_cell_data(cell_data, decoded_field_type, field_rev)
|
SelectOptionTypeOptionTransformer::transform_type_option_cell_data(
|
||||||
|
self,
|
||||||
|
cell_data,
|
||||||
|
decoded_field_type,
|
||||||
|
field_rev,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn displayed_cell_string(
|
fn displayed_cell_string(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::entities::FieldType;
|
use crate::entities::FieldType;
|
||||||
use crate::impl_type_option;
|
use crate::impl_type_option;
|
||||||
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
|
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
|
||||||
|
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformer;
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||||
use crate::services::field::{
|
use crate::services::field::{
|
||||||
SelectOptionCellChangeset, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction,
|
SelectOptionCellChangeset, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction,
|
||||||
@ -96,7 +97,7 @@ impl TypeOptionBuilder for SingleSelectTypeOptionBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transform(&mut self, field_type: &FieldType, type_option_data: String) {
|
fn transform(&mut self, field_type: &FieldType, type_option_data: String) {
|
||||||
self.0.transform_type_option(field_type, type_option_data);
|
SelectOptionTypeOptionTransformer::transform_type_option(&mut self.0, field_type, type_option_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
use crate::entities::FieldType;
|
||||||
|
use crate::services::cell::{CellBytes, CellData};
|
||||||
|
use crate::services::field::{
|
||||||
|
SelectOptionColorPB, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction, CHECK, UNCHECK,
|
||||||
|
};
|
||||||
|
use flowy_error::FlowyResult;
|
||||||
|
use flowy_grid_data_model::revision::FieldRevision;
|
||||||
|
|
||||||
|
/// Handles how to transform the cell data when switching between different field types
|
||||||
|
pub struct SelectOptionTypeOptionTransformer();
|
||||||
|
impl SelectOptionTypeOptionTransformer {
|
||||||
|
pub fn transform_type_option<T>(shared: &mut T, field_type: &FieldType, _type_option_data: String)
|
||||||
|
where
|
||||||
|
T: SelectTypeOptionSharedAction,
|
||||||
|
{
|
||||||
|
match field_type {
|
||||||
|
FieldType::Checkbox => {
|
||||||
|
//add Yes and No options if it does not exist.
|
||||||
|
if !shared.options().iter().any(|option| option.name == CHECK) {
|
||||||
|
let check_option = SelectOptionPB::with_color(CHECK, SelectOptionColorPB::Green);
|
||||||
|
shared.mut_options().push(check_option);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !shared.options().iter().any(|option| option.name == UNCHECK) {
|
||||||
|
let uncheck_option = SelectOptionPB::with_color(UNCHECK, SelectOptionColorPB::Yellow);
|
||||||
|
shared.mut_options().push(uncheck_option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FieldType::MultiSelect => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_type_option_cell_data<T>(
|
||||||
|
shared: &T,
|
||||||
|
cell_data: CellData<SelectOptionIds>,
|
||||||
|
decoded_field_type: &FieldType,
|
||||||
|
_field_rev: &FieldRevision,
|
||||||
|
) -> FlowyResult<CellBytes>
|
||||||
|
where
|
||||||
|
T: SelectTypeOptionSharedAction,
|
||||||
|
{
|
||||||
|
match decoded_field_type {
|
||||||
|
FieldType::SingleSelect | FieldType::MultiSelect => {
|
||||||
|
//
|
||||||
|
CellBytes::from(shared.get_selected_options(cell_data))
|
||||||
|
}
|
||||||
|
FieldType::Checkbox => {
|
||||||
|
// transform the cell data to the option id
|
||||||
|
let mut transformed_ids = Vec::new();
|
||||||
|
let options = shared.options();
|
||||||
|
cell_data.try_into_inner()?.iter().for_each(|name| {
|
||||||
|
if let Some(option) = options.iter().find(|option| &option.name == name) {
|
||||||
|
transformed_ids.push(option.id.clone());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let transformed_cell_data = CellData::from(SelectOptionIds::from(transformed_ids));
|
||||||
|
CellBytes::from(shared.get_selected_options(transformed_cell_data))
|
||||||
|
}
|
||||||
|
_ => Ok(CellBytes::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -112,7 +112,7 @@ pub struct ASTField<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ASTField<'a> {
|
impl<'a> ASTField<'a> {
|
||||||
pub fn new(cx: &Ctxt, field: &'a syn::Field, index: usize) -> Self {
|
pub fn new(cx: &Ctxt, field: &'a syn::Field, index: usize) -> Result<Self, String> {
|
||||||
let mut bracket_inner_ty = None;
|
let mut bracket_inner_ty = None;
|
||||||
let mut bracket_ty = None;
|
let mut bracket_ty = None;
|
||||||
let mut bracket_category = Some(BracketCategory::Other);
|
let mut bracket_category = Some(BracketCategory::Other);
|
||||||
@ -144,15 +144,16 @@ impl<'a> ASTField<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
cx.error_spanned_by(&field.ty, "fail to get the ty inner type");
|
let msg = format!("Fail to get the ty inner type: {:?}", field);
|
||||||
|
return Err(msg);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("ASTField parser failed: {:?} with error: {}", field, e);
|
eprintln!("ASTField parser failed: {:?} with error: {}", field, e);
|
||||||
panic!()
|
return Err(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTField {
|
Ok(ASTField {
|
||||||
member: match &field.ident {
|
member: match &field.ident {
|
||||||
Some(ident) => syn::Member::Named(ident.clone()),
|
Some(ident) => syn::Member::Named(ident.clone()),
|
||||||
None => syn::Member::Unnamed(index.into()),
|
None => syn::Member::Unnamed(index.into()),
|
||||||
@ -163,7 +164,7 @@ impl<'a> ASTField<'a> {
|
|||||||
bracket_ty,
|
bracket_ty,
|
||||||
bracket_inner_ty,
|
bracket_inner_ty,
|
||||||
bracket_category,
|
bracket_category,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_as_str(&self) -> String {
|
pub fn ty_as_str(&self) -> String {
|
||||||
@ -235,6 +236,6 @@ fn fields_from_ast<'a>(cx: &Ctxt, fields: &'a Punctuated<syn::Field, Token![,]>)
|
|||||||
fields
|
fields
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, field)| ASTField::new(cx, field, index))
|
.flat_map(|(index, field)| ASTField::new(cx, field, index).ok())
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -74,8 +74,7 @@ pub fn parse_ty<'a>(ctxt: &Ctxt, ty: &'a syn::Type) -> Result<Option<TyInfo<'a>>
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ctxt.error_spanned_by(ty, "Unsupported inner type, get inner type fail".to_string());
|
Err("Unsupported inner type, get inner type fail".to_string())
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_bracketed(bracketed: &AngleBracketedGenericArguments) -> Vec<&syn::Type> {
|
fn parse_bracketed(bracketed: &AngleBracketedGenericArguments) -> Vec<&syn::Type> {
|
||||||
|
Reference in New Issue
Block a user