"Composition over inheritance" does not mean "replace inheritance with composition". Composition alone is less powerful than inheritance, because inheritance is composition plus shared behavior plus some other stuff. If all you had in Rust was everything that's in Java, but no inheritance, Rust would be a less capable language.
The point of composition over inheritance (in my interpretation) is that because composition is less powerful, you can use it in more places, and combine it with other tools to make more flexible abstractions that are better suited to any given problem. The number of problems that actually call for exactly inheritance is... well, surprisingly small. So...
- Instead of defining behavior (with associated data) in a class and overriding it in subclasses, which requires multiple inheritance to modify behavior along more than one dimension, you could make objects that represent specific behaviors (with associated data) and compose them in the object that has the behavior, which works for any number of behaviors.
- Instead of using a subclass to modify the behavior of a superclass, you can create wrappers that implement the same interface by deferring to the inner value, which can be mixed and matched at runtime if desired.
- Sometimes all you really need is an enum.
- Sometimes your "base class" should really just be a generic wrapper that you "specialize" with different type parameters. (sorry no reference link for this one)
In general, you should not expect to take a class-based design with pervasive use of inheritance and just replace all the inheritance with something else. It may work, but it will not be as coherent as if you start from your system requirements and sketch up a new design without using inheritance. You may even find that the use of inheritance was gratuitous to begin with and the design is cleaner, less coupled and faster without it.