I'm a Rust noob (and mostly-Python expert) attempting to write a simple CLI program in Rust as a means of getting to learn more of the language.
My question is mostly a design question, although if you are interested in some code I've written so far, it's up on Github - https://github.com/yuvadm/slingr
Details aside the essence of this program has to do 3 things:
- Provide a nice CLI (which I'm mostly basing on
clap) that wraps all the user interaction
- A thread that captures user-generated keystrokes that control the program
- A thread that handles asynchronous UDP traffic (sending and receiving)
What is the best way to structure this program? I'm trying to get rid of my OOP way of thinking and use more proper Rust idioms - such as traits and
mpsc for thread communication. Ideally I'd like to have these three components separated by these lines, but I'm open to hearing other ways of achieving this.
The basic structure for a Rust binary program would look something like this.
--keystrokelibs // Folder with mod.rs produces project::keystrokelibs::*
--asyncudp // Another folder with mod.rs produces project::asyncudp::*
--lib.rs // Top level library for your project, essentially your library entry point
--main.rs // This is your binary application that handles all front end stuff
I hope that was helpful. If you haven't already, you should read the book. It covers this.
Thanks for the reply @Germanicus. What you wrote makes sense, but actually what I was going for was more about how the threads communicate with each other, where the
mpsc channels are created and who owns them, and how the general data structure should look like for each of the components.
I'd do the clap stuff in the main function most likely. Surely you don't need any interaction with this but if course after getting started? You might consider StructOpt or my very young ClapMe to make getting the data out of your command like flags easier.
For the keystrokes and networking I think your idea of using two threads communicating with a channel or two would be practical and pretty easy to manage. The key question there is how the interaction goes both ways. Is there a state machine that needs management? If so, you'll have to decide which thread holds it.