this post was submitted on 13 Apr 2023
7 points (100.0% liked)

Rust Programming

8159 readers
1 users here now

founded 5 years ago
MODERATORS
 

I would like to know if there are any proposals for internal file organization, like what to put from top to bottom...

Example: start with pub use declarations, then use, the mod, enums, traits, etc.

I've seen rustfmt has some options like reorder_imports that may impose some partial structure, but I would like a more comprehensive guide/spec...

If there's nothing like that. Can we maybe discuss something that makes sense? πŸ€”

top 6 comments
sorted by: hot top controversial new old
[–] Ephera@lemmy.ml 3 points 2 years ago (1 children)

I usually sort them like this and feel like that's roughly what most people are doing:

  • Imports from third-party libraries
  • Imports from std
  • Imports from own crate
  • mod statements and respective (pub use) imports from sub-modules
  • pub types & functions
  • private types & functions
  • Unit tests

Generally, the logic is public API at the top, internals at the bottom, so that other devs using your module find everything they need at the top.

One exception to that are the imports. Aside from pub use, those would be better placed at the bottom. We just seem to put them up top for reasons of We've Always Done It This Wayβ„’.

[–] lemming_7765@lemmy.ml 1 points 2 years ago (1 children)

That's more or less what I do. However I usually struggle with enum, traits, functions and structs inside the same group. So, for example, if I'm in the public group:

  1. do I mix them all and sort alphabetically or hierarchically (like the post https://lemmy.ml/comment/414806 suggests)?
  2. do I put enums, traits and functions first since they are usually prerequisites for the following types? Meaning that an enum will probably be used in a struct or trait, so we may want to present it before to the reader.
  3. any other sorting....

πŸ€”

[–] Ephera@lemmy.ml 2 points 2 years ago (1 children)

I would also definitely recommend hierarchical sorting. So, at the top would be a type typically used when calling your API or the aggregate type holding your internal state etc. and then right below each of these, the types they are composed of.

Reading code requires sifting through tons of complexity and it requires not-sifting through irrelevant complexity. So, I want to know that I need a type before I care about its precise definition.

For multiple, not hierarchically related types, I try to put the most important, most frequently used type at the top.

And I usually put types above functions, as functions can entail a lot of code + details, so I don't want them 'displacing' any relevant types.

But yeah, I'm not a fan of hard rules and there's definitely exceptions to these.

In a codebase at $DAYJOB, we often have Configuration types, which are just boilerplate to read out part of a config file and make it easily accessible to the code in this module.
No one cares how those Configuration types look, so we place them below all the functions.

And sometimes, you'll have a module with many types and not really a reason to deem one more important than the other. Then just sorting them alphabetically can be more readable.

[–] lemming_7765@lemmy.ml 2 points 2 years ago

Makes sense. I've also given a try to the flags I mentioned in rustfmt and they are apparently just for the nightly build, which makes me think they are working on it, which is good news (at least for me).

Sometimes having too much freedom when it comes to organizing code can be worse, I guess. But in general I prefer it to, for example, C, which was so picky with the placements of things.

Thanks for the feedback πŸ‘

[–] scouten@ericscouten.social 2 points 2 years ago (1 children)

@lemming_7765 since things can be expressed in more or less any order, I like the idea of putting the most important things first and then working down from there.

Not my original idea but I can’t remember the origin.

[–] lemming_7765@lemmy.ml 1 points 2 years ago

So, hierarchichal top down, I guess. With main types before subordinate ones. Right?