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

Unify builders' patterns #2853

Open
MichaelScofield opened this issue Dec 1, 2023 · 3 comments
Open

Unify builders' patterns #2853

MichaelScofield opened this issue Dec 1, 2023 · 3 comments
Labels
good first issue Good for newcomers

Comments

@MichaelScofield
Copy link
Collaborator

What type of enhancement is this?

Refactor

What does the enhancement do?

Currently we have a lot of builders with multiple patterns:

  • some are using with_field_name to set their values while others are using field_name directly;
  • take &mut self and self differently;
  • derived from derive-builder crate's builder or not

To make our codes look better, let's unify all these builders' patterns:

  • if possible, derived from typed-builder instead of derive-builder. typed-builder looks more promising (see its "Alternatives" section in its readme)
  • take self and return self
  • use with_field_name

Implementation challenges

No response

@MichaelScofield MichaelScofield added the good first issue Good for newcomers label Dec 1, 2023
@evenyag
Copy link
Contributor

evenyag commented Dec 1, 2023

In some circumstances, taking &mut self is more convenient. e.g. pushing some elements into the builder in a loop.

@tisonkun
Copy link
Collaborator

tisonkun commented Dec 2, 2023

@evenyag Can you demostrate the code?

// &mut self

let mut builder = ...;
for ... {
  builder.with_xxx(...);
}

// self
let mut builder = ...;
for ... {
  builder = builder.with_xxx(...);
}

In my illustration, those two flavor in loop seems quite similar.

For add elements -

pub struct Builder {
  ns: Vec<u64>
}

impl Builder {
  fn add_n(&mut self, n: u64) {
    self.ns.push(n);
  }

  fn add_n(mut self, n: u64) -> Self {
    self.ns.push(n);
    self
  }
}

A possible argument is that not always the full ownership is easily to take. This decision happened also when I choose mut key: Vec<u8> from key: &mut Vec<u8> for ChrootKvBackend's methods. But as long as we take control for the world, it should be doable by fostering the codebase.

@evenyag
Copy link
Contributor

evenyag commented Dec 4, 2023

The assignment is annoying and looks different from other invocation of setters.

let mut builder = RegionMetadataBuilder::new(self.region_id);
for column in &self.column_metadatas {
    builder = builder.push_column_metadata(column.clone());
}
builder.primary_key(self.primary_key.clone());

We only use the assignment inside the for loop. However, it is just a minor style problem but not a blocker for this issue.

A possible argument is that not always full ownership is easily to take.

Yes, this is possible if we want to reuse the builder or work with a trait object (the MutableVector trait). However, it is possible to unify most builders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants