Skip to content

Commit

Permalink
Merge pull request #6 from hylo-so/narrow-widen
Browse files Browse the repository at this point in the history
Add widen and narrow functions
  • Loading branch information
0xPlish authored Mar 18, 2024
2 parents 3d9ae22 + d453539 commit d2fdff5
Showing 1 changed file with 38 additions and 13 deletions.
51 changes: 38 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,41 @@ impl<Bits, Base, Exp> Fix<Bits, Base, Exp> {
}
}

/// Converts the underlying bits to another type.
/// This operation can lose precision (e.g. u128 -> u8).
/// Converts the underlying bits to a wider type.
///
/// # Examples
///
/// ```
/// use fix::aliases::si::Milli;
/// let one = Milli::new(16899u64);
/// let mapped = one.widen::<u128>();
/// assert_eq!(mapped, Milli::new(16899u128));
/// ```
///
pub fn widen<ToBits>(self) -> Fix<ToBits, Base, Exp>
where
ToBits: From<Bits>,
{
Fix::<ToBits, Base, Exp>::new(self.bits.into())
}

/// Attempts to converts underlying bits to a narrower type.
/// Returns `None` if conversion fails.
///
/// # Examples
///
/// ```
/// use fix::aliases::si::Milli;
/// let one = Milli::new(16899u128);
/// let mapped = one.map_bits(|b| b as u64);
/// assert_eq!(mapped, Milli::new(16899u64));
/// let mapped = one.narrow::<u64>();
/// assert_eq!(mapped, Some(Milli::new(16899u64)));
/// ```
///
pub fn map_bits<ToBits, F>(self, f: F) -> Fix<ToBits, Base, Exp>
pub fn narrow<ToBits>(self) -> Option<Fix<ToBits, Base, Exp>>
where
F: Fn(Bits) -> ToBits,
ToBits: TryFrom<Bits>,
{
Fix::<ToBits, Base, Exp>::new(f(self.bits))
self.bits.try_into().ok().map(Fix::<ToBits, Base, Exp>::new)
}
}

Expand Down Expand Up @@ -800,16 +818,23 @@ mod tests {
}

#[test]
fn map_bits_lossless() {
fn narrow_succeeds() {
let one = Milli::new(1000u128);
let mapped = one.map_bits(|b| b as u64);
assert_eq!(mapped, Milli::new(1000u64));
let mapped = one.narrow::<u64>();
assert_eq!(mapped, Some(Milli::new(1000u64)));
}

#[test]
fn map_bits_lossy() {
fn narrow_fails() {
let one = Milli::new(1699u64);
let mapped = one.map_bits(|b| b as u8);
assert_eq!(mapped, Milli::new(163u8));
let mapped = one.narrow::<u8>();
assert_eq!(mapped, None);
}

#[test]
fn widen_succeeds() {
let one = Milli::new(1340191u64);
let mapped = one.widen::<u128>();
assert_eq!(mapped, Milli::new(1340191u128));
}
}

0 comments on commit d2fdff5

Please sign in to comment.