Pretty easy way to implement this strategy: avoid using Vec to the extremes. It is quite common in Rust programs that there’s tons of Vec instances, while in reality most of them are fixed arrays on their usage patterns. In addition heapless provides pretty nice set of structures for common tasks with a fixed amount data space.
I really like this heapless. It sort of helps to implement my strategy for developing Rust programs:
1.Maximize no_std surface. 2 Minimize heap allocations.
It is easier to see then the hot zones where the program actually dynamically grows for a good reason, similarly as with unsafe blocks it is easy to the red zones for memory errors. This helps a lot with availability and protection against denial-of-service (DoS) attacks.
So to summarize I don’t split Rust program in my mind just to “unsafe” and “safe” but instead I split it “unsafe”, “static” and “dynamic”, or along the lines.
really like this fsmetry crate (also no_std):
fsmentry::dsl! {
#[derive(Debug)]
pub Mode {
WaitingInput -> WaitingCommand -> WaitingInput;
WaitingCommand -> SendingFile -> WaitingInput;
WaitingCommand -> ReceivingFile -> WaitingInput;
WaitingCommand -> Exit;
}
}
I use it manage life-cycle in my small serial port tool tior. I also have some #zmodem code together but it is apparently much bigger leap to implement the #cli interface than it is to implement the protocol. I had to take some time to refactor existing code (e.g. to put FSM in place) and now I’m doing file path auto-completing interface for sending and receiving files with zmodem.
For the text input I’m going to use inquire.
I guess the definition of feature complete for 0.1 version is fully working zmodem transfers and known bugs have been fixed. Right now there is a single known bug: https://github.com/jarkkojs/tior/issues/1.
i guess i could create a completely new crate to the crate ecosystem called rmodem with initially just with ZCBIN implementation but sort of BufReader/Writer approach towards integration.