As part of an experiment at work I had a go at rewriting some code for communicating with a microcontroller in Rust. Thanks to custom derives, I was able to replace a couple thousand lines of code (including one gnarly 1000+ line switch statement!) with 20-something trivial struct declarations and a custom derive which weighed in at less than a hundred lines.
I know a lot of people have put lots of hard work into the macro system and thanks to all of you!
I can't really share the code, but the general idea is I would create a couple important traits in the root crate:
pub trait Message{
fn encode<W: Write>(&self, writer: W) -> Result<(), Error>;
fn description(&self) -> &'static str;
}
pub trait MessageField {
fn encode_field<W: Write>(&self, writer: W) -> Result<(), Error>;
}
Then write out a couple structs like so,
#[derive(Debug, Copy, Clone, PartialEq, Message)]
#[msg(mnemonic = "RLXX", description = "Run the bootloader")]
pub struct RunBootloader;
#[derive(Debug, Copy, Clone, PartialEq, Message)]
#[msg(mnemonic = "PPXX", description = "Default program pause for op")]
pub struct ProgramPause {
pub duration: Option<usize>,
pub next_operation: usize,
}
Which then expands to something like this:
impl Message for RunBootloader {
fn encode<W: Write>(&self, writer: W) -> Result<(), Error> {
write!(writer, "RLXX")?;
Ok(())
}
fn description(&self) -> &'static str {
"Run the bootloader"
}
}
impl Message for ProgramPause {
fn encode<W: Write>(&self, writer: W) -> Result<(), Error> {
write!(writer, "PPXX")?;
if let Some(value) = self.duration {
value.encode_field(&mut writer)?;
}
self.next_operation.encode_field(&mut writer)?;
Ok(())
}
fn description(&self) -> &'static str {
"Default program pause for op"
}
}
As an afterthough, does anyone know if there are any resources for implementing your own custom derives? I got pretty far by just skimming the syn
and quote
docs as well as structopt_derive
's source code, but it'd be nice if there were something akin to The Little Book of Rust Macros ("The Little Book of Macros 2.0"?).