All classes have this as base class. I was wondering how this can be done. I have read few blogs which suggest the enum approach, trait approach. but none of this see natural. What are the other options? Is there something like Go's embedding planned or possible?
Note, I am not planning to rewrite the project, just curious to see how it will look like
That looks very much like a database-heavy project. I'm guessing the goal is/was to have all those fields in all SQL tables?
I wouldn't know a solution from the top of my head, but two things that come to mind would be:
Generate the classes by macro:
db_struct! {
// Macro implementation magically inserts common fields,
// can even do defaults
my_field1: foo,
my_field2: bar
}
This probably is simplest for ORMs (Diesel!) to interpret (I hope)
Second: embed the Base-struct as a field in all structs. If you make sure that there is a Default impl for Base, the user wouldn't even have to init it thanks to the default-init syntax as explained here on StackOverflow (that was surprisingly hard to find, do we have a documentation problem here?)
Mix and match the above: make a macro that inserts the fields and generates the default impl. (Or use #[derive(default)] )
Just some stabs in the dark to get the discussion started
@juleskers Thank you. I like the macro approach. Macros and compiler plugin are so powerful, i am excited to see how frameworks are going to use/abuse them. I also found this RFC which proposes to have fields in trait. that might solve some of the issues.
I did not know about Default trait, like you said there is no mention of it in docs I believe. Thanks again for this.
While there are probably some good use cases for having fields in traits, there are certainly ways to to get around of this too using getters and setters.
You can define a trait that looks something like this:
which would implement the getters and setters for your DbEntry while placing all your meta data in your self.base field. Then you could even implement something of an "Abstract Base Class" for extending the functionality with things that satisfy BaseMeta, with something like:
It will be in the appendix of The Book, 2nd edition, "21.3 C: derivable traits".
The "update syntax" as it's called is mentioned in The Book, 1st edition, in the structure section, 3.12, but doesn't make the jump to combining it with Default.
I've opened an issue to discuss this here
In my experience with java, getters/setters are becoming almost an anti-pattern, at least in the java-bean style that is most common. They promote/imply mutable state everywhere. This gives up a big advantage that rust provides with its immutable-by-default strategy.
Of course, you can't call the setters on an immutable binding, you need &mut Self, so the problem isn't as bad as it gets in java.