Whether I should use private static functions in impl or private static functions in module


On one side methods in module has no indentation. On another side methods in impl grouped together.


Does the function make sense being associated with that type?

Does it directly return an instance of that type, i.e. is it a constructor? Does it make sense for that method to be recognized as a constructor for that type, rather than a function that does some work and returns an instance as a result? For example, std::thread::spawn() shouldn’t be considered a constructor of JoinHandle because its purpose isn’t primarily to create the handle: the handle is just the result of spawning a new thread.

Does it take an instance of that type or reference to it but doesn’t want to be an instance method? For example, the static methods on std::rc::Rc can’t be instance methods because they could potentially interfere with methods called through its Deref impl. However, they operate directly on it so it makes sense to have them associated with it.

In these cases, it makes sense as a static method.

If it’s just a function that’s useful to the type but doesn’t directly refer to it–for example, a function called by a few of the type’s methods but isn’t provided an instance of the type itself–then it belongs as a module-level function.

Also, a rare case where a module-level function makes more sense than a static method is if the function takes a raw pointer (*const T or *mut T) to a type. You see this most often with extern functions, which can’t be methods because methods marked extern don’t really work and don’t make much sense in the first place, given that no other language would know how to call them.

However, this exception also has an exception: when the raw pointer is used to reconstruct the original type (such as Box::from_raw())–in this case, it’s basically a very special (and usually unsafe) constructor.

It’s mostly about what “feels right” to you, but following convention helps other Rust programmers who might want to look at or extend your code later on down the road. This includes yourself, because you’re not always going to remember exactly how you did things; having sensibly organized code will help you pick things back up faster when you come back to it later.