I need to build a byte array that represents commands to a device. It may look something like this:
let cmds = [
0x01, // cmd 1
0x02, // cmd 2
0x03, 0xaa, 0xbb, // cmd 3
0x04, // cmd 4
0x05, 0xaa, // cmd 5
];
Some commands take parameters, some don't. Some parameters require calculations. Each command is fixed in size, so it's known at compile time how big the array needs to be.
It'd be nice to construct it like this, where I abstract groups of bytes into commands:
let cmds = [
cmd1(),
cmd2(),
cmd3(0, true, [3, 4]),
cmd4(),
cmd5(0xaa)
];
I haven't found any way to do this with functions or macros. I am in no_std
, so I am not using collections.
How to achieve something resembling this in Rust?
You can have each command function return an array or
Vec
of bytes:And then build your commands like so:
This builds an array of slices of bytes. To get the full stream of bytes, use
flatten
:You can make this more elaborate by returning some types that implement a
Command
trait and collecting them into an array of trait objects, but I'll leave that up to OP.Edit: Here's a macro that can build the array directly, using the
arrayvec
crate:If you're worried about performance, this example compiles the array into a single instruction:
See it on the playground. Its limited to types that are
Copy
. The length of the array must be supplied. It will panic at runtime if the array size doesn't match the combined size of the results.