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:
Nathan.fooo
2022-10-17 14:14:10 +08:00
committed by GitHub
parent aead4dd068
commit 825725df7d
7 changed files with 84 additions and 31 deletions

View File

@ -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::*;

View File

@ -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)]

View File

@ -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(

View File

@ -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)
} }
} }

View File

@ -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()),
}
}
}

View File

@ -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()
} }

View File

@ -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> {