pub struct PaddedNumber<const A: u8 = 1, const B: u8 = { u8::MAX }> { /* private fields */ }Expand description
Newtype encapsulating the padded number invariants
Consists only of an u8 and an u64 which keep track of the
leading zeros count and the remaining number value respectively.
Check out the crate-level documentation for an introduction.
PaddedNumber uses const generic parameters for setting lower (inclusive)
and upper (inclusive) length bounds. These parameters are by default set to
1 and 255 (u8::MAX) respectively.
MIN < MAXallows for variable digit length.MIN == MAXrequires the digit to be exactly of length MIN/MAX.MIN == 0results in empty values (“”) being allowed as valid numbers.MIN > MAX, where MIN, MAX > 0is technically declarable, but any attempts at constructing such a padded number will fail.
Implementations§
Source§impl<const A: u8, const B: u8> PaddedNumber<A, B>
impl<const A: u8, const B: u8> PaddedNumber<A, B>
Sourcepub const fn try_new(str: &str) -> Result<Self, ParsePaddedNumberError>
pub const fn try_new(str: &str) -> Result<Self, ParsePaddedNumberError>
Create a new PaddedNumber
Source§impl<const A: u8, const B: u8> PaddedNumber<A, B>
impl<const A: u8, const B: u8> PaddedNumber<A, B>
Sourcepub fn wrapping_add(self, rhs: u64) -> Self
pub fn wrapping_add(self, rhs: u64) -> Self
Wrapping addition with u64 as right-hand side
Used within the impl Add<u64> for PaddedNumber implementation.
assert_eq!(padded_number!("0") + 1, padded_number!("0").wrapping_add(1));
// Within bounds
assert_eq!(padded_number!("9") + 1, padded_number!("00"));
assert_eq!(padded_number!("80") + 11, padded_number!("91"));
// Wrapped
assert_eq!(
bound_padded_number!(2, 3, "999") + 2,
bound_padded_number!(2, 3, "01")
);Sourcepub fn saturating_add(self, rhs: u64) -> Self
pub fn saturating_add(self, rhs: u64) -> Self
Saturating addition with u64 as right-hand side
assert_eq!(
bound_padded_number!(2, 3, "990").saturating_add(1000),
bound_padded_number!(2, 3, "999") // saturated
);Addition within bounds behaves the same as in Self::wrapping_add.
Sourcepub fn wrapping_sub(self, rhs: u64) -> Self
pub fn wrapping_sub(self, rhs: u64) -> Self
Wrapping subtraction with u64 as right-hand side
Used within the impl Sub<u64> for PaddedNumber implementation.
assert_eq!(padded_number!("9") - 1, padded_number!("9").wrapping_sub(1));
// Within bounds
assert_eq!(padded_number!("9") + 1, padded_number!("00"));
assert_eq!(padded_number!("80") + 11, padded_number!("91"));
// Wrapped
assert_eq!(
bound_padded_number!(2, 3, "999") + 2,
bound_padded_number!(2, 3, "01")
);Sourcepub fn saturating_sub(self, rhs: u64) -> Self
pub fn saturating_sub(self, rhs: u64) -> Self
Saturating subtraction with u64 as right-hand side
assert_eq!(
bound_padded_number!(1, 2, "99").saturating_sub(1000),
bound_padded_number!(1, 2, "0") // saturated
);Subtraction within bounds behaves the same as in Self::wrapping_sub.
Source§impl<const MIN: u8, const MAX: u8> PaddedNumber<MIN, MAX>
impl<const MIN: u8, const MAX: u8> PaddedNumber<MIN, MAX>
Sourcepub fn checked_section<const START_INDEX: u8, const END_INDEX: u8>(
&self,
) -> Option<PaddedNumber<{ _ }, { _ }>>
pub fn checked_section<const START_INDEX: u8, const END_INDEX: u8>( &self, ) -> Option<PaddedNumber<{ _ }, { _ }>>
Get a section of a padded number, missing digits not allowed.
First generic parameter is the start index, inclusive. Second parameter denotes the end index, exclusive. Remaining bound checks are enforced by the type system. E.g. end >= start and end <= max length.
Returns None if the end index overflowed for a padded number whose
length is less than END_INDEX.
Returned max and min sizes always be further relaxed with
PaddedNumber::resize.
§Examples
#![feature(generic_const_exprs)]
let section = padded_number!("00123")
.checked_section::<2, 5>()
.expect("section should not have overflowed");
assert_eq!(section, bound_padded_number!(3, 3, "123"));
let section = bound_padded_number!(1, 3, "0").checked_section::<1, 3>();
// overflowed, missing two digits after "0"
assert!(section.is_none());#![feature(generic_const_exprs)]
let section = bound_padded_number!(3, 3, "123");
section.checked_section::<0, 4>(); // <-- END_INDEX '4' > MAX_LENGTH '3'#![feature(generic_const_exprs)]
let padded_number = bound_padded_number!(3, 3, "123");
section.checked_section::<2, 1>(); // <-- END_INDEX '1' < START_INDEX '2'Sourcepub fn relaxed_section<const START: u8, const END: u8, const NEW_MIN: u8>(
&self,
) -> Option<PaddedNumber<NEW_MIN, { _ }>>
pub fn relaxed_section<const START: u8, const END: u8, const NEW_MIN: u8>( &self, ) -> Option<PaddedNumber<NEW_MIN, { _ }>>
Get a section of a padded number, missing digits allowed.
START, as the names suggests, denotes the start index on the padded
number to select from, inclusive. END index is on the other hand
exclusive.
Remaining bounds are statically verified. E.g.:
START<END,NEW_MIN<=END-START
Returns None if the returned section length would be less than the
specified NEW_MIN parameter. As for the maximum length, END - START
is provided from the method. PaddedNumber::resize can then be used
to relax these bounds even further.
§Examples
#![feature(generic_const_exprs)]
let section = padded_number!("00123")
.relaxed_section::<3, 10, 1>()
.expect("invalid min length");
assert_eq!(section, bound_padded_number!(1, 7, "23"));
let section = bound_padded_number!(1, 10, "00").relaxed_section::<5, 7, 1>();
// no digits between index 5 and 7, and at least 1 was required
assert!(section.is_none());#![feature(generic_const_exprs)]
let section = bound_padded_number!(1, 5, "123");
section.checked_section::<2, 3, 10>(); // <-- NEW_MIN '10' > END '2' - START '1'Sourcepub fn expected_section<const START_INDEX: u8, const END_INDEX: u8>(
&self,
) -> PaddedNumber<{ _ }, { _ }>
pub fn expected_section<const START_INDEX: u8, const END_INDEX: u8>( &self, ) -> PaddedNumber<{ _ }, { _ }>
Get a section from the minimum length of a padded number
Unlike PaddedNumber::checked_section, this does not need to return
an option. Type system ensures that END_INDEX <= MIN_LENGTH.
§Examples
#![feature(generic_const_exprs)]
let section = bound_padded_number!(3, 5, "00123").expected_section::<0, 3>();
assert_eq!(section, bound_padded_number!(3, 3, "001"));#![feature(generic_const_exprs)]
let section = bound_padded_number!(3, 5, "00123");
section.expected_section::<0, 4>(); // <-- END_INDEX '4' > MIN_LENGTH '3'Trait Implementations§
Source§impl<const A: u8, const B: u8> Clone for PaddedNumber<A, B>
impl<const A: u8, const B: u8> Clone for PaddedNumber<A, B>
Source§fn clone(&self) -> PaddedNumber<A, B>
fn clone(&self) -> PaddedNumber<A, B>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more