Skip to content

Commit a565895

Browse files
dueseesgeisler
authored andcommitted
Improved docs, fixed clippy warnings, fixed cargo fmt (#42)
* Documentation * why is Bech32 used? * mention "1" as separator * refer explicitly to original description *for more details* * cargo clippy * rustfmt * removed rustfmt::skip * add automatic travis checks for formatting/clippy Co-authored-by: Sebastian <[email protected]>
1 parent ccbb003 commit a565895

File tree

2 files changed

+78
-44
lines changed

2 files changed

+78
-44
lines changed

.travis.yml

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ script:
1111

1212
jobs:
1313
include:
14+
- stage: best practices
15+
rust: stable
16+
install:
17+
- rustup component add rustfmt
18+
- rustup component add clippy
19+
script:
20+
- rustfmt --check src/lib.rs
21+
- cargo clippy -- -D warnings
1422
- stage: fuzz
1523
before_install:
1624
- sudo apt-get -qq update

src/lib.rs

+70-44
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@
1818
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1919
// THE SOFTWARE.
2020

21-
//! Encoding and decoding Bech32 format
21+
//! Encoding and decoding of the Bech32 format
2222
//!
23-
//! Bech32 is a 5-bit (base-32) encoding scheme that produces strings that comprise
24-
//! a human-readable part, a separator, a data part, and a checksum. The encoding
25-
//! implements a BCH code that guarantees error detection of up to four characters
26-
//! with less than 1 in 1 billion chance of failing to detect more errors.
23+
//! Bech32 is an encoding scheme that is easy to use for humans and efficient to encode in QR codes.
2724
//!
28-
//! The Bech32 encoding was originally formulated in [BIP-0173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)
25+
//! A Bech32 string consists of a human-readable part (HRP), a separator (the character `'1'`), and a data part.
26+
//! A checksum at the end of the string provides error detection to prevent mistakes when the string is written off or read out loud.
27+
//!
28+
//! The original description in [BIP-0173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) has more details.
2929
//!
3030
//! # Examples
3131
//!
32-
//! ```rust
32+
//! ```
3333
//! use bech32::{self, FromBase32, ToBase32};
3434
//!
3535
//! let encoded = bech32::encode("bech32", vec![0x00, 0x01, 0x02].to_base32()).unwrap();
@@ -44,16 +44,15 @@
4444
// Allow trait objects without dyn on nightly and make 1.22 ignore the unknown lint
4545
#![allow(unknown_lints)]
4646
#![allow(bare_trait_objects)]
47-
4847
#![deny(missing_docs)]
4948
#![deny(non_upper_case_globals)]
5049
#![deny(non_camel_case_types)]
5150
#![deny(non_snake_case)]
5251
#![deny(unused_mut)]
5352
#![cfg_attr(feature = "strict", deny(warnings))]
5453

55-
use std::{error, fmt};
5654
use std::borrow::Cow;
55+
use std::{error, fmt};
5756

5857
// AsciiExt is needed for Rust 1.14 but not for newer versions
5958
#[allow(unused_imports, deprecated)]
@@ -75,12 +74,12 @@ impl u5 {
7574
}
7675

7776
/// Returns a copy of the underlying `u8` value
78-
pub fn to_u8(&self) -> u8 {
77+
pub fn to_u8(self) -> u8 {
7978
self.0
8079
}
8180

8281
/// Get char representing this 5 bit value as defined in BIP173
83-
pub fn to_char(&self) -> char {
82+
pub fn to_char(self) -> char {
8483
CHARSET[self.to_u8() as usize]
8584
}
8685
}
@@ -149,10 +148,11 @@ impl<'a> Bech32Writer<'a> {
149148

150149
fn polymod_step(&mut self, v: u5) {
151150
let b = (self.chk >> 25) as u8;
152-
self.chk = (self.chk & 0x1ffffff) << 5 ^ (u32::from(*v.as_ref()));
153-
for i in 0..5 {
151+
self.chk = (self.chk & 0x01ff_ffff) << 5 ^ (u32::from(*v.as_ref()));
152+
153+
for (i, item) in GEN.iter().enumerate() {
154154
if (b >> i) & 1 == 1 {
155-
self.chk ^= GEN[i]
155+
self.chk ^= item;
156156
}
157157
}
158158
}
@@ -173,9 +173,8 @@ impl<'a> Bech32Writer<'a> {
173173
let plm: u32 = self.chk ^ 1;
174174

175175
for p in 0..6 {
176-
self.formatter.write_char(
177-
u5(((plm >> (5 * (5 - p))) & 0x1f) as u8).to_char()
178-
)?;
176+
self.formatter
177+
.write_char(u5(((plm >> (5 * (5 - p))) & 0x1f) as u8).to_char())?;
179178
}
180179

181180
Ok(())
@@ -193,7 +192,8 @@ impl<'a> WriteBase32 for Bech32Writer<'a> {
193192

194193
impl<'a> Drop for Bech32Writer<'a> {
195194
fn drop(&mut self) {
196-
self.inner_finalize().expect("Unhandled error writing the checksum on drop.")
195+
self.inner_finalize()
196+
.expect("Unhandled error writing the checksum on drop.")
197197
}
198198
}
199199

@@ -265,8 +265,8 @@ impl<T: AsRef<[u8]>> ToBase32 for T {
265265
// buffer holds too many bits, so we don't have to combine buffer bits with new bits
266266
// from this rounds byte.
267267
if buffer_bits >= 5 {
268-
writer.write_u5(u5((buffer & 0b11111000) >> 3))?;
269-
buffer = buffer << 5;
268+
writer.write_u5(u5((buffer & 0b1111_1000) >> 3))?;
269+
buffer <<= 5;
270270
buffer_bits -= 5;
271271
}
272272

@@ -277,13 +277,13 @@ impl<T: AsRef<[u8]>> ToBase32 for T {
277277

278278
writer.write_u5(u5(from_buffer | from_byte))?;
279279
buffer = b << (5 - buffer_bits);
280-
buffer_bits = 3 + buffer_bits;
280+
buffer_bits += 3;
281281
}
282282

283283
// There can be at most two u5s left in the buffer after processing all bytes, write them.
284284
if buffer_bits >= 5 {
285-
writer.write_u5(u5((buffer & 0b11111000) >> 3))?;
286-
buffer = buffer << 5;
285+
writer.write_u5(u5((buffer & 0b1111_1000) >> 3))?;
286+
buffer <<= 5;
287287
buffer_bits -= 5;
288288
}
289289

@@ -511,10 +511,11 @@ fn polymod(values: &[u5]) -> u32 {
511511
let mut b: u8;
512512
for v in values {
513513
b = (chk >> 25) as u8;
514-
chk = (chk & 0x1ffffff) << 5 ^ (u32::from(*v.as_ref()));
515-
for i in 0..5 {
514+
chk = (chk & 0x01ff_ffff) << 5 ^ (u32::from(*v.as_ref()));
515+
516+
for (i, item) in GEN.iter().enumerate() {
516517
if (b >> i) & 1 == 1 {
517-
chk ^= GEN[i]
518+
chk ^= item;
518519
}
519520
}
520521
}
@@ -526,26 +527,30 @@ const SEP: char = '1';
526527

527528
/// Encoding character set. Maps data value -> char
528529
const CHARSET: [char; 32] = [
529-
'q','p','z','r','y','9','x','8',
530-
'g','f','2','t','v','d','w','0',
531-
's','3','j','n','5','4','k','h',
532-
'c','e','6','m','u','a','7','l'
530+
'q', 'p', 'z', 'r', 'y', '9', 'x', '8', // +0
531+
'g', 'f', '2', 't', 'v', 'd', 'w', '0', // +8
532+
's', '3', 'j', 'n', '5', '4', 'k', 'h', // +16
533+
'c', 'e', '6', 'm', 'u', 'a', '7', 'l', // +24
533534
];
534535

535536
/// Reverse character set. Maps ASCII byte -> CHARSET index on [0,31]
536537
const CHARSET_REV: [i8; 128] = [
537-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
538-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
539-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
540-
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
541-
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
542-
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
543-
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
544-
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
538+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
539+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
540+
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23,
541+
-1, 18, 22, 31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, -1, 29,
542+
-1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1,
543+
-1, -1, -1, -1,
545544
];
546545

547546
/// Generator coefficients
548-
const GEN: [u32; 5] = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
547+
const GEN: [u32; 5] = [
548+
0x3b6a_57b2,
549+
0x2650_8e6d,
550+
0x1ea1_19fa,
551+
0x3d42_33dd,
552+
0x2a14_62b3,
553+
];
549554

550555
/// Error types for Bech32 encoding / decoding
551556
#[derive(Copy, Clone, PartialEq, Debug)]
@@ -669,7 +674,11 @@ mod tests {
669674
for s in strings {
670675
let decode_result = decode(s);
671676
if !decode_result.is_ok() {
672-
panic!("Did not decode: {:?} Reason: {:?}", s, decode_result.unwrap_err());
677+
panic!(
678+
"Did not decode: {:?} Reason: {:?}",
679+
s,
680+
decode_result.unwrap_err()
681+
);
673682
}
674683
assert!(decode_result.is_ok());
675684
let decoded = decode_result.unwrap();
@@ -707,7 +716,12 @@ mod tests {
707716
println!("{:?}", dec_result.unwrap());
708717
panic!("Should be invalid: {:?}", s);
709718
}
710-
assert_eq!(dec_result.unwrap_err(), expected_error, "testing input '{}'", s);
719+
assert_eq!(
720+
dec_result.unwrap_err(),
721+
expected_error,
722+
"testing input '{}'",
723+
s
724+
);
711725
}
712726
}
713727

@@ -720,7 +734,13 @@ mod tests {
720734
(vec![0x01], 8, 8, true, vec![0x01]),
721735
(vec![0x01], 8, 4, true, vec![0x00, 0x01]),
722736
(vec![0x01], 8, 2, true, vec![0x00, 0x00, 0x00, 0x01]),
723-
(vec![0x01], 8, 1, true, vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]),
737+
(
738+
vec![0x01],
739+
8,
740+
1,
741+
true,
742+
vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01],
743+
),
724744
(vec![0xff], 8, 5, true, vec![0x1f, 0x1c]),
725745
(vec![0x1f, 0x1c], 5, 8, false, vec![0xff]),
726746
];
@@ -770,7 +790,10 @@ mod tests {
770790
assert!([0u8, 1, 2, 30, 31, 255].check_base32().is_err());
771791

772792
assert!([1u8, 2, 3, 4].check_base32().is_ok());
773-
assert_eq!([30u8, 31, 35, 20].check_base32(), Err(Error::InvalidData(35)));
793+
assert_eq!(
794+
[30u8, 31, 35, 20].check_base32(),
795+
Err(Error::InvalidData(35))
796+
);
774797
}
775798

776799
#[test]
@@ -784,7 +807,10 @@ mod tests {
784807
#[test]
785808
fn from_base32() {
786809
use FromBase32;
787-
assert_eq!(Vec::from_base32(&[0x1f, 0x1c].check_base32().unwrap()), Ok(vec![0xff]));
810+
assert_eq!(
811+
Vec::from_base32(&[0x1f, 0x1c].check_base32().unwrap()),
812+
Ok(vec![0xff])
813+
);
788814
assert_eq!(
789815
Vec::from_base32(&[0x1f, 0x1f].check_base32().unwrap()),
790816
Err(Error::InvalidPadding)

0 commit comments

Comments
 (0)