Skip to content

Commit

Permalink
Replace std's padding with impl based on ufmt
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Oct 8, 2023
1 parent 069df6e commit a6678c1
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 27 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ register-access = { path = "register-access" }
gui = { path = "gui" }
macros = { path = "macros" }
embassy-alloc-taskpool = { path = "embassy-alloc-taskpool" }
ads129x = { path = "ads129x" }
max17055 = { path = "max17055", optional = true }
ads129x = { path = "ads129x", features = ["ufmt-impl"] }
max17055 = { path = "max17055", optional = true, features = ["ufmt-impl"] }
signal-processing = { workspace = true }
replace_with = { version = "0.1", default-features = false, features = [
"nightly",
Expand Down
2 changes: 2 additions & 0 deletions ads129x/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ register-access = { path = "../register-access" }
logger = { workspace = true }
log = { workspace = true, optional = true }
defmt = { workspace = true, optional = true }
ufmt = { workspace = true, optional = true }

[features]
default = []
defmt = ["dep:defmt", "logger/defmt", "device-descriptor/defmt"]
log = ["dep:log", "logger/log"]
ufmt-impl = ["dep:ufmt", "device-descriptor/ufmt-impl"]
2 changes: 2 additions & 0 deletions device-descriptor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ edition = "2021"

[dependencies]
defmt = { workspace = true, optional = true }
ufmt = { workspace = true, optional = true }

[features]
default = []
defmt = ["dep:defmt"]
ufmt-impl = ["dep:ufmt"]
1 change: 1 addition & 0 deletions device-descriptor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ macro_rules! define_register_type {
}) => {
#[derive(PartialEq, Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "ufmt-impl", derive(ufmt::derive::uDebug))]
pub enum $type {
$(
$(#[$variant_attr])*
Expand Down
2 changes: 2 additions & 0 deletions max17055/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ register-access = { path = "../register-access" }
defmt = { workspace = true, optional = true }
log = { workspace = true, optional = true }
logger = { workspace = true }
ufmt = { workspace = true, optional = true }

[features]
default = []
defmt = ["dep:defmt", "device-descriptor/defmt", "logger/defmt"]
log = ["dep:log", "logger/log"]
ufmt-impl = ["dep:ufmt", "device-descriptor/ufmt-impl"]
128 changes: 127 additions & 1 deletion src/human_readable.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use defmt::Format;
use embassy_time::Duration;
use ufmt::{uDisplay, uwrite};
use ufmt::{uDebug, uDisplay, uwrite};

const STEPS: &[(usize, &str)] = &[(1024, "k"), (1024 * 1024, "M"), (1024 * 1024 * 1024, "G")];

Expand Down Expand Up @@ -64,3 +64,129 @@ impl Format for Throughput {
}
}
}

#[allow(clippy::collapsible_else_if)]
const fn digits(value: u32) -> usize {
if value < 10_000 {
if value < 100 {
if value < 10 {
1
} else {
2
}
} else {
if value < 1_000 {
3
} else {
4
}
}
} else if value < 100_000_000 {
if value < 1_000_000 {
if value < 100_000 {
5
} else {
6
}
} else {
if value < 10_000_000 {
7
} else {
8
}
}
} else {
if value < 1_000_000_000 {
9
} else {
10
}
}
}

fn write_padding<W>(f: &mut ufmt::Formatter<'_, W>, len: usize, n: usize) -> Result<(), W::Error>
where
W: ufmt::uWrite + ?Sized,
{
const PADS: [&str; 5] = ["", " ", " ", " ", " "];

let mut pad_length = n.saturating_sub(len);

while pad_length >= 5 {
f.write_str(" ")?;
pad_length -= 5;
}
f.write_str(PADS[pad_length])
}

#[derive(Clone, Copy, PartialEq)]
pub struct LeftPad(pub usize, pub i32);

impl uDisplay for LeftPad {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt::uWrite + ?Sized,
{
let len = if self.1 < 0 {
digits(self.1.unsigned_abs()) + 1 // +1 for the minus sign
} else {
digits(self.1 as u32)
};

write_padding(f, len, self.0)?;

uwrite!(f, "{}", self.1)
}
}

struct LengthCounter(usize);
impl ufmt::uWrite for LengthCounter {
type Error = core::convert::Infallible;

fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
self.0 += s.len();
Ok(())
}
}

#[derive(Clone, Copy, PartialEq)]
pub struct LeftPadAny<D>(pub usize, pub D);

impl<D: uDisplay> uDisplay for LeftPadAny<D> {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt::uWrite + ?Sized,
{
let mut counter = LengthCounter(0);
unwrap!(ufmt::uwrite!(&mut counter, "{}", self.1));

write_padding(f, counter.0, self.0)?;

ufmt::uwrite!(f, "{}", self.1)
}
}

impl<D: uDebug> uDebug for LeftPadAny<D> {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt::uWrite + ?Sized,
{
let mut counter = LengthCounter(0);
unwrap!(ufmt::uwrite!(&mut counter, "{:?}", self.1));

write_padding(f, counter.0, self.0)?;

ufmt::uwrite!(f, "{:?}", self.1)
}
}

#[macro_export]
macro_rules! uformat {
($len:literal, $($arg:tt)*) => {
{
let mut s = heapless::String::<$len>::new();
unwrap!(ufmt::uwrite!(&mut s, $($arg)*));
s
}
}
}
5 changes: 2 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ use crate::{

mod board;
mod heap;
mod human_readable;
pub mod human_readable;
mod replace_with;
mod sleep;
mod stack_protection;
Expand Down Expand Up @@ -111,8 +111,7 @@ impl ufmt::uDisplay for SerialNumber {

impl core::fmt::Display for SerialNumber {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut serial = heapless::String::<12>::new();
unwrap!(ufmt::uwrite!(&mut serial, "{}", self));
let serial = uformat!(12, "{}", self);
f.write_str(&serial)
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/states/menu/about.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::{
board::initialized::Board,
human_readable::LeftPadAny,
states::menu::{AppMenu, AppMenuBuilder, MenuScreen},
AppState, SerialNumber,
uformat, AppState, SerialNumber,
};

use alloc::{borrow::Cow, format};
use embedded_menu::items::NavigationItem;
use gui::screens::create_menu;

Expand Down Expand Up @@ -35,23 +35,23 @@ impl MenuScreen for AboutAppMenu {

let mut items = heapless::Vec::<_, 5>::new();
items.extend([
list_item(Cow::from(env!("FW_VERSION_MENU_ITEM"))),
list_item(Cow::from(env!("HW_VERSION_MENU_ITEM"))),
list_item(uformat!(20, "{}", env!("FW_VERSION_MENU_ITEM"))),
list_item(uformat!(20, "{}", env!("HW_VERSION_MENU_ITEM"))),
NavigationItem::new(
Cow::from(format!("Serial {}", SerialNumber)),
uformat!(20, "Serial {}", SerialNumber),
AboutMenuEvents::ToSerial,
),
list_item(Cow::from(match board.frontend.device_id() {
Some(id) => format!("ADC {:>16}", format!("{id:?}")),
None => format!("ADC Unknown"),
})),
list_item(match board.frontend.device_id() {
Some(id) => uformat!(20, "ADC {:?}", LeftPadAny(16, id)),
None => uformat!(20, "ADC Unknown"),
}),
]);

#[cfg(feature = "battery_max17055")]
{
unwrap!(items
.push(
NavigationItem::new(Cow::from("Fuel gauge"), AboutMenuEvents::ToBatteryInfo)
NavigationItem::new(uformat!(20, "Fuel gauge"), AboutMenuEvents::ToBatteryInfo)
.with_marker("MAX17055")
)
.ok());
Expand Down
34 changes: 23 additions & 11 deletions src/states/menu/battery_info.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{
board::initialized::Board,
human_readable::LeftPad,
states::menu::{AppMenu, AppMenuBuilder, MenuScreen},
AppState,
uformat, AppState,
};
use alloc::format;
use embassy_time::Duration;
use embedded_menu::items::NavigationItem;
use gui::screens::create_menu;
Expand Down Expand Up @@ -40,27 +40,39 @@ impl MenuScreen for BatteryInfoMenu {
let mut sensor = board.battery_monitor.sensor().await;

if let Ok(voltage) = sensor.fg.read_vcell().await {
list_item(format!("Voltage {:>10}mV", voltage / 1000));
list_item(uformat!(
20,
"Voltage {}mV",
LeftPad(10, voltage as i32 / 1000)
));
}

if let Ok(current) = sensor.fg.read_current().await {
list_item(format!("Current {:>10}mA", current / 1000));
list_item(uformat!(
20,
"Current {}mA",
LeftPad(10, current as i32 / 1000)
));
}

if let Ok(capacity) = sensor.fg.read_design_capacity().await {
list_item(format!("Nominal {:>9}mAh", capacity / 1000));
if let Ok(cap) = sensor.fg.read_design_capacity().await {
list_item(uformat!(20, "Nominal {}mAh", LeftPad(9, cap as i32 / 1000)));
}

if let Ok(capacity) = sensor.fg.read_reported_capacity().await {
list_item(format!("Capacity {:>8}mAh", capacity / 1000));
if let Ok(cap) = sensor.fg.read_reported_capacity().await {
list_item(uformat!(
20,
"Capacity {}mAh",
LeftPad(8, cap as i32 / 1000)
));
}

if let Ok(age) = sensor.fg.read_cell_age().await {
list_item(format!("Cell age {:>10}%", age));
list_item(uformat!(20, "Cell age {}%", LeftPad(10, age as i32)));
}

if let Ok(charge_cycles) = sensor.fg.read_charge_cycles().await {
list_item(format!("Charge cycles {:>6}", charge_cycles));
if let Ok(cycles) = sensor.fg.read_charge_cycles().await {
list_item(uformat!(20, "Charge cycles {}", LeftPad(6, cycles as i32)));
}

create_menu("Battery info")
Expand Down
3 changes: 3 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ fn asm() -> AnyResult<()> {
.stdout_path("target/syms.txt")
.run()?;

std::fs::remove_file("target/asm_filt.s").ok();
std::fs::remove_file("target/syms_filt.txt").ok();

cmd!("rustfilt", "-i=target/asm.s", "-o=target/asm_filt.s").run()?;
cmd!("rustfilt", "-i=target/syms.txt", "-o=target/syms_filt.txt").run()?;

Expand Down

0 comments on commit a6678c1

Please sign in to comment.