use crate::{Boundary1d, Cmp, ConstInit, is};
#[doc = crate::_tags!(fmt num)]
#[doc = crate::_doc_location!("text/fmt")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FmtNumGroup {
pub left_len: u8,
pub right_len: u8,
pub left_sep: Option<char>,
pub right_sep: Option<char>,
}
#[rustfmt::skip]
impl Default for FmtNumGroup { fn default() -> Self { Self::INIT } }
impl ConstInit for FmtNumGroup {
const INIT: Self = Self {
left_len: 3,
right_len: 0,
left_sep: None,
right_sep: None,
};
}
#[rustfmt::skip]
impl FmtNumGroup {
const _SIZE: () = const { assert![size_of::<Self>() == 12]; };
#[inline(always)]
pub const fn new() -> Self { Self::INIT }
pub const fn rust() -> Self { Self::INIT.with_sep('_') }
pub const fn both_rust() -> Self { Self::INIT.with_sep('_').with_len(3) }
pub const fn rust_hex() -> Self { Self::INIT.with_left(4, '_') }
pub const fn both_rust_hex() -> Self { Self::INIT.with_sep('_').with_len(4) }
pub const fn with_left_len(mut self, len: u8) -> Self { self.left_len = len; self }
pub const fn with_right_len(mut self, len: u8) -> Self { self.right_len = len; self }
pub const fn with_left_sep(mut self, sep: char) -> Self { self.left_sep = Some(sep); self }
pub const fn without_left_sep(mut self) -> Self { self.left_sep = None; self }
pub const fn with_right_sep(mut self, sep: char) -> Self { self.right_sep = Some(sep); self }
pub const fn without_right_sep(mut self) -> Self { self.right_sep = None; self }
pub const fn with_len(mut self, len: u8) -> Self {
self.left_len = len; self.right_len = len; self }
pub const fn with_sep(mut self, sep: char) -> Self {
self.left_sep = Some(sep); self.right_sep = Some(sep); self }
pub const fn without_sep(mut self) -> Self {
self.left_sep = None; self.right_sep = None; self }
pub const fn has_left(&self) -> bool { self.left_len != 0 && self.left_sep.is_some() }
pub const fn has_right(&self) -> bool { self.right_len != 0 && self.right_sep.is_some() }
pub const fn is_enabled(&self) -> bool { self.has_left() || self.has_right() }
pub const fn with_left(mut self, len: u8, sep: char) -> Self {
self.left_len = len; self.left_sep = Some(sep); self }
pub const fn with_right(mut self, len: u8, sep: char) -> Self {
self.right_len = len; self.right_sep = Some(sep); self }
}
impl FmtNumGroup {
pub const fn side_len(&self, side: Boundary1d) -> u8 {
match side {
Boundary1d::Lower => self.left_len,
Boundary1d::Upper => self.right_len,
}
}
pub const fn side_sep(&self, side: Boundary1d) -> Option<char> {
match side {
Boundary1d::Lower => self.left_sep,
Boundary1d::Upper => self.right_sep,
}
}
pub const fn side_enabled(&self, side: Boundary1d) -> bool {
self.side_len(side) != 0 && self.side_sep(side).is_some()
}
pub const fn digits_for_grouped_width(
&self,
side: Boundary1d,
digit_count: u16,
min_width: u16,
) -> u16 {
is![!self.side_enabled(side), return Cmp(digit_count).max(min_width)];
let len = self.side_len(side) as u16;
let mut digits = Cmp((min_width * len) / (len + 1)).max(digit_count);
let seps = (digits.saturating_sub(1)) / len;
is![digits + seps < min_width, digits += 1];
digits
}
}