For example, I have lots of variants of Commands, all of them could be
Parsed from &str
Execute Commands
use Display to show what they are doing.
I know that, we could just wrote 3 functions, parse, execute and display, and perform the logic in those functions.
But Since those commands have a strong inner-relationship (e.g., if I decided to change the parse behavior, the execute and display behavior might also be changed) and no matter what Command::MoveMouse is done, Command::Sleep won't be affected. Thus I want to seperate those functions into seperate files:
Your own suggestion is already good. It lets you pass the commands around as an enum when you don't need to know what's inside, and as a command struct once you have checked it and need to do command specific stuff. I would probably do it like that or use free functions, depending on their content and what I need to do.
I like to point at IpAddr in std::net - Rust for this: make types for the individual things, then just stuff them all in an enum. Maybe there's then some common stuff you can define on the enum too, or maybe the reason it's best as an enum instead of a Box<dyn Foo> is that there really isn't much, and everything just matches on it.
If the operations have the same fn signature for each enum variant (parse, execute and display), you can define a trait for the operations, implement it for each variant's struct, and use enum_dispatch to call them. enum_dispatch implements the trait for the enum as a whole, and this implementation does the match for you.