dsync icon indicating copy to clipboard operation
dsync copied to clipboard

Use a Trait to organize functions

Open dessalines opened this issue 3 years ago • 6 comments

Hey, one of the creators of lemmy here, this looks like a really interesting project that could help us. We have a lot of tables, and generating a lot of the simpler Crud-type functions in code would make this really useful.

Instead of pub struct UpdateTodo and exporting that, I highly recommend creating a trait. Here's what we do in our code:

pub trait Crud {
  type Form;
  type IdType; // We use diesel-newtypes to make sure all the Ids are unit structs, to make sure people aren't using a `PostId` when they should be using a `CommentId` for example... using `i32` can be dangerous.
  fn create(conn: &mut Connection, form: &Self::Form) -> Result<Self, Error>
    where Self: Sized;
  fn read(conn: &mut Connection, id: Self::IdType) -> Result<Self, Error> 
  ...

Then your generated code would be:

impl Crud for XXX {
  type Form = XXXForm;
  fn read(...

And people could easily import Crud to get all the functions.

dessalines avatar Oct 03 '22 17:10 dessalines

Ah, neat! I like that you're using PostId instead of i32. I wanted to add column type overrides in the generation config for cases like this.

Could I ask why you prefer traits though? If it's just a preference, I wouldn't mind if dsync had both options!

Wulf avatar Oct 04 '22 17:10 Wulf

Couple reasons:

  • All of these generated tables have the same distinct set of functions, so it makes sense to do a trait for them.
  • You only have to import the trait to be able access all the functions, rather than having a ton of imports.
  • Possibly have some default functions / shared behavior.

dessalines avatar Oct 04 '22 20:10 dessalines

hey @dessalines, sorry I dropped the ball here -- it's been a busy few weeks. Do you mind creating a PR for this? I think trait-based generation is a good idea moving forward :)

Wulf avatar Oct 25 '22 19:10 Wulf

I pry wouldn't have time for it, with my work on lemmy unfortunately. but somebody else could also take a stab at it.

dessalines avatar Oct 25 '22 21:10 dessalines

The issue I see with trying this is that a trait can't cover instances where there are multiple primary keys

at least not without some major refactoring of the codebase (passing a collection (that can have an arbitrary number of elements each with different data types, which I'm not sure exists for rust) instead of having a parameter per primary key)

AnthonyMichaelTDM avatar Nov 29 '22 01:11 AnthonyMichaelTDM

on second thought, using macros could work as macros can be variadic

AnthonyMichaelTDM avatar Jan 21 '23 21:01 AnthonyMichaelTDM