diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 9025e2e..2ff1c03 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -10,6 +10,21 @@ env: CARGO_TERM_COLOR: always jobs: + msrv: + name: MSRV (1.85) + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v7 + - name: Install Rust 1.85 + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.85.0 + - name: Check library + run: | + cargo check --package ur --lib + cargo check --package ur --lib --no-default-features + build: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index a82ed8e..772587d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ license = "MIT" version = "0.5.0" authors = ["Dominik Spicher "] edition = "2024" +rust-version = "1.85" repository = "https://github.com/dspicher/ur-rs/" [workspace] members = ["examples/wasm", "fuzz"] diff --git a/src/bytewords.rs b/src/bytewords.rs index fde9e33..2bacc14 100644 --- a/src/bytewords.rs +++ b/src/bytewords.rs @@ -115,7 +115,7 @@ pub fn decode(encoded: &str, style: Style) -> Result, Error> { } fn decode_minimal(encoded: &str) -> Result, Error> { - if !encoded.len().is_multiple_of(2) { + if encoded.len() % 2 != 0 { return Err(Error::InvalidLength); } diff --git a/src/fountain.rs b/src/fountain.rs index 6952126..7b8913d 100644 --- a/src/fountain.rs +++ b/src/fountain.rs @@ -140,6 +140,7 @@ impl From> for Error { #[derive(Debug)] pub struct Encoder { parts: Vec>, + fragment_count: usize, message_length: usize, checksum: u32, current_sequence: usize, @@ -177,8 +178,10 @@ impl Encoder { } let fragment_length = fragment_length(message.len(), max_fragment_length); let fragments = partition(message.to_vec(), fragment_length); + let fragment_count = fragments.len(); Ok(Self { parts: fragments, + fragment_count, message_length: message.len(), checksum: crate::crc32().checksum(message), current_sequence: 0, @@ -211,7 +214,7 @@ impl Encoder { /// See the [`crate::fountain`] module documentation for an example. pub fn next_part(&mut self) -> Part { self.current_sequence += 1; - let indexes = choose_fragments(self.current_sequence, self.parts.len(), self.checksum); + let indexes = choose_fragments(self.current_sequence, self.fragment_count, self.checksum); let mut mixed = alloc::vec![0; self.parts[0].len()]; for item in indexes { @@ -220,7 +223,7 @@ impl Encoder { Part { sequence: self.current_sequence, - sequence_count: self.parts.len(), + sequence_count: self.fragment_count, message_length: self.message_length, checksum: self.checksum, data: mixed, @@ -238,7 +241,7 @@ impl Encoder { /// ``` #[must_use] pub const fn fragment_count(&self) -> usize { - self.parts.len() + self.fragment_count } /// Returns whether all original segments have been emitted at least once. @@ -262,7 +265,7 @@ impl Encoder { /// [`current_sequence`]: Encoder::current_sequence #[must_use] pub const fn complete(&self) -> bool { - self.current_sequence >= self.parts.len() + self.current_sequence >= self.fragment_count } } @@ -901,12 +904,17 @@ mod tests { #[test] fn test_fountain_encoder_is_complete() { + const fn progress(encoder: &Encoder) -> (usize, bool) { + (encoder.fragment_count(), encoder.complete()) + } + let message = crate::xoshiro::test_utils::make_message("Wolf", 256); let mut encoder = Encoder::new(&message, 30).unwrap(); - for _ in 0..encoder.parts.len() { + assert_eq!(progress(&encoder), (9, false)); + for _ in 0..encoder.fragment_count() { encoder.next_part(); } - assert!(encoder.complete()); + assert_eq!(progress(&encoder), (9, true)); } #[test] diff --git a/src/ur.rs b/src/ur.rs index d352c20..174b38b 100644 --- a/src/ur.rs +++ b/src/ur.rs @@ -430,6 +430,10 @@ mod tests { #[test] fn test_ur_encoder() { + const fn fragment_count(encoder: &Encoder<'_>) -> usize { + encoder.fragment_count() + } + let ur = make_message_ur(256, "Wolf"); let mut encoder = Encoder::bytes(&ur, 30).unwrap(); let expected = vec![ @@ -454,7 +458,7 @@ mod tests { "ur:bytes/19-9/lpbwascfadaxcywenbpljkhdcadekicpaajootjzpsdrbalpeywllbdsnbinaerkurspbncxgslgftvtsrjtksplcpeo", "ur:bytes/20-9/lpbbascfadaxcywenbpljkhdcayapmrleeleaxpasfrtrdkncffwjyjzgyetdmlewtkpktgllepfrltataztksmhkbot", ]; - assert_eq!(encoder.fragment_count(), 9); + assert_eq!(fragment_count(&encoder), 9); for (index, e) in expected.into_iter().enumerate() { assert_eq!(encoder.current_index(), index); assert_eq!(encoder.next_part().unwrap(), e);