also, abstract your communication transport. in C++ this is easy to do as an abstract base class, in Rust you would define a trait interface.
The bulk of your code should not know it is talking over USB.
Now if you ever want to talk to your microcontroller over TCP/IP you can implement a new transport and not have to rewrite absolutely everything.