I like to write them in blocks of concerns: ie there should be the minimum amount of jumping around the file when reading them. If there are a lot of these separate blocks in a single file, that is a good indication that it has grown enough and it is time to separate them into different files. But inside the blocks it would be usually struct/enums (no implicit order since they are just sum/product types), impl blocks, free functions (that are usually common functionality between the impl blocks).
I don't have any hard rules for things beyond whatever makes things easier to read. And I will move things around to get to the goal as I see fit (sometimes this can change over time - especially if you come back to something after a few months).
Generally speaking I would start with more global types at the top, though I might have some types next to the functions when they are only used by the function. And for functions I would start with main followed by functions main uses in rough order that they appear. With functions used by other functions below that functions - sometimes below others if I care more about the flow of higher functions more. Whatever I find makes it easier to read from top to bottom basically. I do the same with types, define the main ones first, then followed by types they use or types you will want to be aware of next. I don't care what the type is - I don't group enums together - they are all just types to me and it is often better to mix up their order based on how important they are rather than what type they technically are.
I really dislike how so many languages force you to do the reverse of this and declare things before you use them. IMO that is like reading a book starting at the last chapter and means you often have to skip over loads of things to figure out where the start is. Much better to have the most important part at the top of the file.
@boblaw0 In an order that tells the story, when reading the module file top-to-bottom. It is usually difficult to do when rapidly developing, but easier to achieve when refactoring a working program or a library.