Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

类型转换为 ActiveModel 过于冗余 #155

Open
Goodjooy opened this issue Jul 30, 2023 · 4 comments · May be fixed by #158
Open

类型转换为 ActiveModel 过于冗余 #155

Goodjooy opened this issue Jul 30, 2023 · 4 comments · May be fixed by #158

Comments

@Goodjooy
Copy link
Contributor

Goodjooy commented Jul 30, 2023

现状

当前情况下

  • Checked 转换为 ActiveModel
  • Checked 更新作用于 ActiveModel
  • Model 转换为 View
    都会带来要将整个Model 的每一个field 手动遍历一次,有一定冗余与重复

如以下接口,就存在比较大重复,并当代码增长后不易于阅读

impl IntoActiveModel<ActiveModel> for CeobeOperationAppVersion {
    fn into_active_model(self) -> ActiveModel {
        let CeobeOperationAppVersion {
            version,
            force,
            last_force_version,
            description,
        } = self;
        let now = get_now_naive_date_time();
        ActiveModel {
            version: Set(version),
            force: Set(force),
            last_force_version: Set(last_force_version),
            description: Set(description),
            create_at: Set(now),
            modify_at: Set(now),
            ..Default::default()
        }
    }
}

希望的改进方式

通过一组 derive macro 提供以上功能的自动派生

  • DeriveToActiveModel attr: model_conv
    • attr[container]
      • target: 转换/更新的目标model
      • preprocessing optional: 在转换前执行的一个或多个操作,可以要求获取0个或者多个原类型field 所有权
        • var_name optional: 预处理的返回结果的变量名称
        • process: 预处理本身,为一个函数
        • update_skip | update_only optional: 当更新时忽略这个预处理过程 | 只有更新时执行
        • requires optional: 需要获取原类型的参数,顺序为process 参数顺序
          • name : 需要的field 名称
          • onwner| mut_ref optional: 默认为获取不可变引用,可以通过指定为 onwner(所有权) 或者 mut-ref(可变引用)被获取所有权的field 会自动ignore
          • require_self optional: processing 需要 &self, 可以指定为 mut 以获得可变引用
      • default_non_exist optional: 不存在的colume 使用default 填充
      • generate_fields k-v pair optional: 生成的fields, 来自于preprocessing
    • attr[field]
      • rename optional: 默认情况,field IdentActiveModel 一致,可以通过该attr 更改指定field
      • project optional: 对原始类型进行转换
      • ignore optional: 视为该field 不存在
      • condition_set optional: 使用条件赋值,当条件满足将Set ,否则无修改(into 使用默认, update 不更改)
        • condition: 判定函数,第一个参数为 该field 原始值所有权,后续参数可以通过requires 定义
        • requires optional : 需要的参数,只能来自 preprocessing 结果,只能获取不可变引用
  • DeriveUpdateActiveModel attr: model_conv 与 DeriveToActiveModel` 使用相同参数,但是生成Update 代码
  • DeriveViewFromModel attr: model_conv 与 DeriveToActiveModel` 使用相同参数,但是生成Model -> View 代码

可能的代码样例

use Model::ActiveModel
#[derive(DeriveToActiveModel,DeriveUpdateActiveModel)]
#[model_conv(
    preprocessing(
       var_name="now",
       update_skip
       process = “get_now_naive_date_time”,
    ),
    preprocessing(
       update_only
       process = “|this|this.now_update(),
       require_self="mut"
    ),
    default_non_exist,
    generate_fields(
        access_time = "now"
    )
)]
struct Checked {
    #[model_conv(
    rename=“foo_name”
    )]
    foo: int,
    #[model_conv(
    project=“Into<String>::into”
    )]
    bar: Version,
}
@Goodjooy
Copy link
Contributor Author

  • 对于 DeriveToActiveModel 即实现 IntoActiveModel
  • 对于 DeriveUpdateActiveModel 需要trait 辅助
trait ActiveModelUpdater{
  type ActiveModel
  fn update_active_model(self, active:&mut Self::ActiveModel) ;
}

// help trait
trait ActiveModelUpdate<Updater:ActiveModelUpdater<ActiveModel = Self>>{
  fn update(&mut self, updater:Updater){
    updater.udate_active_model(self);
  }
}
  • 对于 DeriveModelConvView 就是实现 impl From<Model> for View

@Goodjooy
Copy link
Contributor Author

@phidiaLam 要不来试试写macro? 总不能只有我写吧?

@phidiaLam
Copy link
Member

@phidiaLam 要不来试试写macro? 总不能只有我写吧?

这个急吗,不急等版本发完我学学试试

This was linked to pull requests Aug 4, 2023
@Goodjooy
Copy link
Contributor Author

Goodjooy commented Aug 4, 2023

@phidiaLam 要不来试试写macro? 总不能只有我写吧?

这个急吗,不急等版本发完我学学试试

不算太急,但是复杂度感觉挺高的,你愿意来那我就写注释好了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants