Implement full SSD1306 OLED display support: - Splash screen on boot (1.5s) with project name, version, board - Dashboard showing radio state, config, counters, RSSI/SNR - RSSI history sparkline (64-sample ring buffer, 2px-wide bars) - DisplayOn/DisplayOff host commands routed via dedicated channel - Pure render functions against generic DrawTarget (no hardware coupling) - Display on/off control bypasses radio task entirely Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
48 lines
1.1 KiB
Rust
48 lines
1.1 KiB
Rust
use proc_macro::TokenStream;
|
|
use syn::{parse::Error, spanned::Spanned, AttrStyle, Attribute};
|
|
|
|
pub(crate) enum WhiteListCaller {
|
|
Interrupt,
|
|
}
|
|
|
|
pub(crate) fn check_attr_whitelist(
|
|
attrs: &[Attribute],
|
|
caller: WhiteListCaller,
|
|
) -> Result<(), TokenStream> {
|
|
let whitelist = &[
|
|
"doc",
|
|
"link_section",
|
|
"cfg",
|
|
"allow",
|
|
"warn",
|
|
"deny",
|
|
"forbid",
|
|
"cold",
|
|
"ram",
|
|
"inline",
|
|
];
|
|
|
|
'o: for attr in attrs {
|
|
for val in whitelist {
|
|
if eq(attr, val) {
|
|
continue 'o;
|
|
}
|
|
}
|
|
|
|
let err_str = match caller {
|
|
WhiteListCaller::Interrupt => {
|
|
"this attribute is not allowed on an interrupt handler controlled by esp-hal"
|
|
}
|
|
};
|
|
|
|
return Err(Error::new(attr.span(), err_str).to_compile_error().into());
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Returns `true` if `attr.path` matches `name`
|
|
fn eq(attr: &Attribute, name: &str) -> bool {
|
|
attr.style == AttrStyle::Outer && attr.path().is_ident(name)
|
|
}
|