Idiomatic way for structs and traits

Let's say in a project, I have some_module/ which contains mod.rs, trait_1.rs, trait_2.rs, common.rs. In common.rs I define some structs

pub struct S1 {
    field1: u8,
    field2: i32,
    ...
}

pub struct S2 {
    field1: u8,
    field2: i32,
    ...
}
...

If in trait_1.rs I define some trait T1, I need to implement it for a number of structs from common.rs, what's the idiomatic way of doing this? I noticed that if the structs are defined in mod.rs, then I can access all fields within the struct from trait_1.rs if I put use crate::some_module::*;, but I read that you should avoid putting logic in mod.rs (correct me if I'm wrong here).

On the other hand, if I define the structs in common.rs, then all private fields are no longer accessible in trait_1.rs, and if I were to make the fields public it kinda defeats the purpose, since some traits require implementation of specific getters and setters for private fields.

You can pub(crate) your struct fields, but I think normally, you'd just implement the traits next to the structs.

1 Like

So it's better to separate trait implementations into separate files as opposed to separate trait declarations in separate files? For instance, it's better to have traits.rs with all the trait definitions and each some_struct.rs would implement all the necessary traits for that one struct?

No. These sort of rules are extremely superficial. Rust — thankfully — isn't Java. You don't structure your code around language features and low-level coding details such as whether some construct is a trait, struct, or enum.

Instead, you should organize your code following the semantics of the domain you are modeling. Put stuff together that belongs together – if that means a trait, a UDT, and an impl in the same file, then go for it.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.