Skip to content

Commit fc2c1d1

Browse files
authored
Implement Display, FromStr and Hash (#44)
* Implement Display, FromStr and Hash * Renovate actions * Fix CI
1 parent 6322d49 commit fc2c1d1

File tree

11 files changed

+139
-21
lines changed

11 files changed

+139
-21
lines changed

.github/workflows/coverage.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
name: coverage
22

3-
# on: [ push, pull_request ]
43
on: [ push ]
54

65
jobs:
76
build:
87
runs-on: ubuntu-latest
98

109
steps:
11-
- uses: actions/checkout@v2
10+
- uses: actions/checkout@v4
1211
with:
1312
fetch-depth: 0
13+
14+
- name: Install Rust toolchain
15+
uses: dtolnay/rust-toolchain@stable
16+
1417
- name: Push to coveralls.io
1518
env:
1619
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}

.github/workflows/pre-commit.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ jobs:
66
pre-commit:
77
runs-on: ubuntu-latest
88
steps:
9-
- uses: actions/checkout@v2
9+
- uses: actions/checkout@v4
1010
- uses: actions/setup-python@v2
1111
- uses: actions-rs/toolchain@v1
1212
with:
1313
toolchain: stable
1414
components: rustfmt, clippy
15-
- uses: pre-commit/action@v2.0.0
15+
- uses: pre-commit/action@v3.0.1

.github/workflows/rust.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ env:
77

88
jobs:
99
build:
10-
1110
runs-on: ubuntu-latest
1211

1312
steps:
14-
- uses: actions/checkout@v2
13+
- uses: actions/checkout@v4
14+
15+
- name: Install Rust toolchain
16+
uses: dtolnay/rust-toolchain@stable
17+
1518
- name: Build
1619
run: cargo build --verbose
1720
- name: Run tests

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
repos:
1616
- repo: https://github.com/pre-commit/pre-commit-hooks
17-
rev: v3.4.0
17+
rev: v5.0.0
1818
hooks:
1919
- id: trailing-whitespace
2020
- id: end-of-file-fixer

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fixed-bigint"
3-
version = "0.1.14"
3+
version = "0.1.15"
44
authors = ["kaidokert <kaidokert@gmail.com>"]
55
documentation = "https://docs.rs/fixed-bigint"
66
edition = "2018"

src/fixeduint/prim_int_impl.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ impl<T: MachineWord, const N: usize> num_traits::PrimInt for FixedUInt<T, N> {
4141
let b = self << (Self::BIT_SIZE - bits as usize);
4242
a | b
4343
}
44-
fn signed_shl(self, _: u32) -> Self {
45-
todo!()
44+
fn signed_shl(self, bits: u32) -> Self {
45+
self.unsigned_shl(bits)
4646
}
47-
fn signed_shr(self, _: u32) -> Self {
48-
todo!()
47+
fn signed_shr(self, bits: u32) -> Self {
48+
self.unsigned_shr(bits)
4949
}
5050
fn unsigned_shl(self, bits: u32) -> Self {
5151
core::ops::Shl::<u32>::shl(self, bits)

src/fixeduint/string_conversion.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use num_traits::Zero;
1+
use core::fmt::Write;
2+
use num_traits::{Num, ToPrimitive, Zero};
23

34
use super::{make_empty_error, make_overflow_err, make_parse_int_err, FixedUInt, MachineWord};
45

@@ -55,3 +56,49 @@ where
5556
self.hex_fmt(formatter, false)
5657
}
5758
}
59+
60+
impl<T: MachineWord, const N: usize> core::fmt::Display for FixedUInt<T, N> {
61+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
62+
const MAX_DIGITS: usize = 20;
63+
64+
if self.is_zero() {
65+
return f.write_char('0');
66+
}
67+
68+
// 20 is sized for u64
69+
let mut digit_blocks = [[0u8; MAX_DIGITS]; N];
70+
let mut digit_count = 0;
71+
let mut number = *self;
72+
let ten = Self::from(10u8);
73+
74+
// Extract digits into our storage
75+
while !number.is_zero() && digit_count < N * MAX_DIGITS {
76+
let (quotient, remainder) = number.div_rem(&ten);
77+
let digit = remainder.to_u8().unwrap();
78+
79+
let block_idx = digit_count / MAX_DIGITS;
80+
let digit_idx = digit_count % MAX_DIGITS;
81+
digit_blocks[block_idx][digit_idx] = b'0' + digit;
82+
83+
digit_count += 1;
84+
number = quotient;
85+
}
86+
87+
// Write digits in reverse order
88+
for i in (0..digit_count).rev() {
89+
let block_idx = i / MAX_DIGITS;
90+
let digit_idx = i % MAX_DIGITS;
91+
f.write_char(digit_blocks[block_idx][digit_idx] as char)?;
92+
}
93+
94+
Ok(())
95+
}
96+
}
97+
98+
impl<T: MachineWord, const N: usize> core::str::FromStr for FixedUInt<T, N> {
99+
type Err = core::num::ParseIntError;
100+
101+
fn from_str(s: &str) -> Result<Self, Self::Err> {
102+
Self::from_str_radix(s, 10)
103+
}
104+
}

src/fixeduint/to_from_bytes.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use super::MachineWord;
22

33
#[cfg(feature = "use-unsafe")]
4-
use core::{
5-
borrow::{Borrow, BorrowMut},
6-
hash::Hash,
7-
};
4+
use core::borrow::{Borrow, BorrowMut};
5+
6+
use core::hash::Hash;
87

98
#[cfg(feature = "zeroize")]
109
use zeroize::DefaultIsZeroes;
@@ -76,10 +75,9 @@ impl<T: MachineWord, const N: usize> AsMut<[u8]> for BytesHolder<T, N> {
7675
self.as_byte_slice_mut()
7776
}
7877
}
79-
#[cfg(feature = "use-unsafe")]
8078
impl<T: MachineWord, const N: usize> Hash for BytesHolder<T, N> {
81-
fn hash<H: core::hash::Hasher>(&self, _state: &mut H) {
82-
todo!()
79+
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
80+
self.array.hash(state)
8381
}
8482
}
8583

src/machineword.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub trait MachineWord:
2828
+ num_traits::FromBytes
2929
+ num_traits::ToBytes
3030
+ Default
31+
+ core::hash::Hash
3132
{
3233
type DoubleWord: num_traits::PrimInt;
3334
fn to_double(self) -> Self::DoubleWord;

tests/integer.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ fn test_divides() {
3737
fn divides<T: num_integer::Integer + From<u8>>() {
3838
let tests = [(6u8, 3u8, true), (8, 2, true), (8, 1, true), (17, 2, false)];
3939
for &(multiple, multiplier, expected) in &tests {
40-
assert_eq!(multiple.is_multiple_of(&multiplier), expected);
40+
assert_eq!(
41+
num_integer::Integer::is_multiple_of(&multiple, &multiplier),
42+
expected
43+
);
4144
assert_eq!(multiple.divides(&multiplier), expected);
4245
}
4346
let divrem = [

0 commit comments

Comments
 (0)