This is a fork of https://github.com/japaric/ufmt, tweaked to play nice with the eBPF kernel verifier.
A (6-40x) smaller, (2-9x) faster and panic-free alternative to
core::fmt
Call graph of a program that formats some structs (generated using
cargo-call-stack
). Source code can be found at the bottom of this file. The
program was compiled with -C opt-level=z
.
From highest priority to lowest priority
-
Optimized for binary size and speed (rather than for compilation time)
-
No dynamic dispatch in generated code
-
No panicking branches in generated code, when optimized
-
No recursion where possible
-
Debug
andDisplay
-like traits -
core::write!
-like macro -
A generic
Formatter<'_, impl uWrite>
instead of a singlecore::Formatter
; theuWrite
trait has an associated error type so each writer can choose its error type. For example, the implementation forstd::String
usesInfallible
as its error type. -
core::fmt::Formatter::debug_struct
-like API -
#[derive(uDebug)]
-
Pretty formatting (
{:#?}
) foruDebug
This crate is guaranteed to compile on stable Rust 1.34 and up. It might compile on older versions but that may change in any new patch release.
All source code (including code snippets) is licensed under either of
-
Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
-
MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.
Full source code in nopanic/examples/struct.rs.
// ..
#[derive(Clone, Copy, uDebug)]
struct Pair {
x: i32,
y: i32,
}
static X: AtomicI32 = AtomicI32::new(0);
static Y: AtomicI32 = AtomicI32::new(0);
#[exception]
fn PendSV() {
let x = X.load(Ordering::Relaxed);
let y = Y.load(Ordering::Relaxed);
uwrite!(&mut W, "{:?}", Braces {}).unwrap();
uwrite!(&mut W, "{:#?}", Braces {}).unwrap();
uwrite!(&mut W, "{:?}", Parens()).unwrap();
uwrite!(&mut W, "{:#?}", Parens()).unwrap();
uwrite!(&mut W, "{:?}", I32(x)).unwrap();
uwrite!(&mut W, "{:#?}", I32(x)).unwrap();
uwrite!(&mut W, "{:?}", Tuple(x, y)).unwrap();
uwrite!(&mut W, "{:#?}", Tuple(x, y)).unwrap();
let pair = Pair { x, y };
uwrite!(&mut W, "{:?}", pair).unwrap();
uwrite!(&mut W, "{:#?}", pair).unwrap();
let first = pair;
let second = pair;
uwrite!(&mut W, "{:?}", Nested { first, second }).unwrap();
uwrite!(&mut W, "{:#?}", Nested { first, second }).unwrap();
}
// ..