flipperzero
flipperzero copied to clipboard
Better string formatting
As a developer, there are currently three main options for formatting strings in Flipper apps:
Safe | Expressiveness | Binary size overhead | |
---|---|---|---|
std::fmt |
✅ | High | High[^1] |
ufmt |
✅ | Low | Low |
sys::furi_string_printf |
❌ | High | None[^2] |
Using std::fmt
is the most flexible and familiar option for developers, but it can add 10+ KB to the overall binary size simply by formatting a single string. While this may be a reasonable trade-off made by an app developer, it's not something we can impose on all users of the flipperzero
crates.
Enter ufmt
which has substantially lower binary overhead, but comes at the expense of expressiveness (no padding/alignment/formatting options, no support for floats) and requires implementing the non-standard ufmt::uDisplay
and ufmt::uWrite
traits.
Finally there is the built-in sys::furi_string_printf
C function, which has no binary-size overhead (it's provided by the Furi runtime), but is problematic to use in Rust because it has a variadic-based interface which is both unsafe and difficult to support in Rust (Rust currently only has limited support for C-variadic functions).
It would be nice to provide an option somewhere in the middle.
[^1]: See #48 and Formatting is Unreasonably Expensive for Embedded Rust [^2]: Provided by Furi runtime
One thought that came to mind was to provide a mechanism for safely using printf
-style functions from Rust (e.g. a procedural macro that generates safe printf calls).
Another possibility would be for us to provide Display
/ Write
traits that allow printf
-style calls to be made internally (while still providing a safe external interface).