@@ -59,78 +59,7 @@ pub mod primitives;
5959
6060#[ cfg( feature = "arrayvec" ) ]
6161use arrayvec:: { ArrayVec , CapacityError } ;
62-
63- /// Integer in the range `0..32`.
64- #[ derive( PartialEq , Eq , Debug , Copy , Clone , Default , PartialOrd , Ord , Hash ) ]
65- #[ allow( non_camel_case_types) ]
66- pub struct u5 ( u8 ) ;
67-
68- impl u5 {
69- /// Returns a copy of the underlying `u8` value.
70- pub fn to_u8 ( self ) -> u8 { self . 0 }
71-
72- /// Gets a character representing this 5 bit value as defined in BIP173.
73- pub fn to_char ( self ) -> char { CHARSET [ self . to_u8 ( ) as usize ] }
74- }
75-
76- impl From < u5 > for u8 {
77- fn from ( v : u5 ) -> u8 { v. 0 }
78- }
79-
80- macro_rules! impl_try_from_upper_bounded {
81- ( $( $ty: ident) +) => {
82- $(
83- impl TryFrom <$ty> for u5 {
84- type Error = TryFromIntError ;
85-
86- /// Tries to create the target number type from a source number type.
87- ///
88- /// # Errors
89- ///
90- /// Returns an error if `value` overflows a `u5`.
91- fn try_from( value: $ty) -> Result <Self , Self :: Error > {
92- if value > 31 {
93- Err ( TryFromIntError :: PosOverflow )
94- } else {
95- let x = u8 :: try_from( value) . expect( "within range" ) ;
96- Ok ( u5( x) )
97- }
98- }
99- }
100- ) +
101- }
102- }
103- macro_rules! impl_try_from_both_bounded {
104- ( $( $ty: ident) +) => {
105- $(
106- impl TryFrom <$ty> for u5 {
107- type Error = TryFromIntError ;
108-
109- /// Tries to create the target number type from a source number type.
110- ///
111- /// # Errors
112- ///
113- /// Returns an error if `value` is outside of the range of a `u5`.
114- fn try_from( value: $ty) -> Result <Self , Self :: Error > {
115- if value < 0 {
116- Err ( TryFromIntError :: NegOverflow )
117- } else if value > 31 {
118- Err ( TryFromIntError :: PosOverflow )
119- } else {
120- let x = u8 :: try_from( value) . expect( "within range" ) ;
121- Ok ( u5( x) )
122- }
123- }
124- }
125- ) +
126- }
127- }
128- impl_try_from_upper_bounded ! ( u8 u16 u32 u64 u128 ) ;
129- impl_try_from_both_bounded ! ( i8 i16 i32 i64 i128 ) ;
130-
131- impl AsRef < u8 > for u5 {
132- fn as_ref ( & self ) -> & u8 { & self . 0 }
133- }
62+ pub use primitives:: gf32:: Fe32 as u5;
13463
13564/// Interface to write `u5`s into a sink.
13665pub trait WriteBase32 {
@@ -306,7 +235,7 @@ write_base_n! { WriteBase32, u5, write_u5 }
306235write_base_n ! { WriteBase256 , u8 , write_u8 }
307236
308237#[ cfg( feature = "arrayvec" ) ]
309- #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
238+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
310239/// Combination of Errors for use with array vec
311240pub enum ComboError {
312241 /// Error from this crate
@@ -712,13 +641,6 @@ fn split_and_decode(s: &str) -> Result<(String, Vec<u5>), Error> {
712641 let data = raw_data
713642 . chars ( )
714643 . map ( |c| {
715- // Only check if c is in the ASCII range, all invalid ASCII
716- // characters have the value -1 in CHARSET_REV (which covers
717- // the whole ASCII range) and will be filtered out later.
718- if !c. is_ascii ( ) {
719- return Err ( Error :: InvalidChar ( c) ) ;
720- }
721-
722644 if c. is_lowercase ( ) {
723645 match case {
724646 Case :: Upper => return Err ( Error :: MixedCase ) ,
@@ -732,15 +654,7 @@ fn split_and_decode(s: &str) -> Result<(String, Vec<u5>), Error> {
732654 Case :: Upper => { }
733655 }
734656 }
735-
736- // c should be <128 since it is in the ASCII range, CHARSET_REV.len() == 128
737- let num_value = CHARSET_REV [ c as usize ] ;
738-
739- if !( 0 ..=31 ) . contains ( & num_value) {
740- return Err ( Error :: InvalidChar ( c) ) ;
741- }
742-
743- Ok ( u5:: try_from ( num_value as u8 ) . expect ( "range checked above, num_value <= 31" ) )
657+ u5:: from_char ( c) . map_err ( Error :: TryFrom )
744658 } )
745659 . collect :: < Result < Vec < u5 > , Error > > ( ) ?;
746660
@@ -788,28 +702,11 @@ where
788702
789703 // Check data payload
790704 for c in raw_data. chars ( ) {
791- // Only check if c is in the ASCII range, all invalid ASCII
792- // characters have the value -1 in CHARSET_REV (which covers
793- // the whole ASCII range) and will be filtered out later.
794- if !c. is_ascii ( ) {
795- Err ( Error :: InvalidChar ( c) ) ?;
796- }
797-
798705 match case {
799706 Case :: Upper => Err ( Error :: MixedCase ) ?,
800707 Case :: None | Case :: Lower => { }
801708 }
802-
803- // c should be <128 since it is in the ASCII range, CHARSET_REV.len() == 128
804- let num_value = CHARSET_REV [ c as usize ] ;
805-
806- if !( 0 ..32 ) . contains ( & num_value) {
807- Err ( Error :: InvalidChar ( c) ) ?;
808- }
809-
810- data. write_u5 (
811- u5:: try_from ( num_value as u8 ) . expect ( "range checked above, num_value <= 31" ) ,
812- ) ?;
709+ data. write_u5 ( u5:: from_char ( c) . map_err ( Error :: TryFrom ) ?) ?;
813710 }
814711
815712 // Ensure checksum
@@ -868,29 +765,11 @@ fn polymod(values: &[u5]) -> u32 {
868765/// Human-readable part and data part separator.
869766const SEP : char = '1' ;
870767
871- /// Encoding character set. Maps data value -> char
872- const CHARSET : [ char ; 32 ] = [
873- 'q' , 'p' , 'z' , 'r' , 'y' , '9' , 'x' , '8' , // +0
874- 'g' , 'f' , '2' , 't' , 'v' , 'd' , 'w' , '0' , // +8
875- 's' , '3' , 'j' , 'n' , '5' , '4' , 'k' , 'h' , // +16
876- 'c' , 'e' , '6' , 'm' , 'u' , 'a' , '7' , 'l' , // +24
877- ] ;
878-
879- /// Reverse character set. Maps ASCII byte -> CHARSET index on [0,31]
880- const CHARSET_REV : [ i8 ; 128 ] = [
881- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
882- -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 ,
883- 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 ,
884- -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 ,
885- -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 ,
886- -1 , -1 , -1 , -1 ,
887- ] ;
888-
889768/// Generator coefficients
890769const GEN : [ u32 ; 5 ] = [ 0x3b6a_57b2 , 0x2650_8e6d , 0x1ea1_19fa , 0x3d42_33dd , 0x2a14_62b3 ] ;
891770
892771/// Error types for Bech32 encoding / decoding.
893- #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
772+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
894773pub enum Error {
895774 /// String does not contain the separator character.
896775 MissingSeparator ,
@@ -907,7 +786,7 @@ pub enum Error {
907786 /// Attempted to convert a value which overflows a `u5`.
908787 Overflow ,
909788 /// Conversion to u5 failed.
910- TryFrom ( TryFromIntError ) ,
789+ TryFrom ( primitives :: gf32 :: Error ) ,
911790}
912791
913792impl From < Infallible > for Error {
@@ -944,8 +823,8 @@ impl std::error::Error for Error {
944823 }
945824}
946825
947- impl From < TryFromIntError > for Error {
948- fn from ( e : TryFromIntError ) -> Self { Error :: TryFrom ( e) }
826+ impl From < primitives :: gf32 :: Error > for Error {
827+ fn from ( e : primitives :: gf32 :: Error ) -> Self { Error :: TryFrom ( e) }
949828}
950829
951830/// Error return when `TryFrom<T>` fails for T -> u5 conversion.
@@ -1132,21 +1011,21 @@ mod tests {
11321011 ( " 1nwldj5" ,
11331012 Error :: InvalidChar ( ' ' ) ) ,
11341013 ( "abc1\u{2192} axkwrx" ,
1135- Error :: InvalidChar ( '\u{2192}' ) ) ,
1014+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( '\u{2192}' ) ) ) ,
11361015 ( "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx" ,
11371016 Error :: InvalidLength ) ,
11381017 ( "pzry9x0s0muk" ,
11391018 Error :: MissingSeparator ) ,
11401019 ( "1pzry9x0s0muk" ,
11411020 Error :: InvalidLength ) ,
11421021 ( "x1b4n0q5v" ,
1143- Error :: InvalidChar ( 'b' ) ) ,
1022+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'b' ) ) ) ,
11441023 ( "ABC1DEFGOH" ,
1145- Error :: InvalidChar ( 'O' ) ) ,
1024+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'O' ) ) ) ,
11461025 ( "li1dgmt3" ,
11471026 Error :: InvalidLength ) ,
11481027 ( "de1lg7wt\u{ff} " ,
1149- Error :: InvalidChar ( '\u{ff}' ) ) ,
1028+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( '\u{ff}' ) ) ) ,
11501029 ( "\u{20} 1xj0phk" ,
11511030 Error :: InvalidChar ( '\u{20}' ) ) ,
11521031 ( "\u{7F} 1g6xzxy" ,
@@ -1158,15 +1037,15 @@ mod tests {
11581037 ( "1qyrz8wqd2c9m" ,
11591038 Error :: InvalidLength ) ,
11601039 ( "y1b0jsk6g" ,
1161- Error :: InvalidChar ( 'b' ) ) ,
1040+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'b' ) ) ) ,
11621041 ( "lt1igcx5c0" ,
1163- Error :: InvalidChar ( 'i' ) ) ,
1042+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'i' ) ) ) ,
11641043 ( "in1muywd" ,
11651044 Error :: InvalidLength ) ,
11661045 ( "mm1crxm3i" ,
1167- Error :: InvalidChar ( 'i' ) ) ,
1046+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'i' ) ) ) ,
11681047 ( "au1s5cgom" ,
1169- Error :: InvalidChar ( 'o' ) ) ,
1048+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'o' ) ) ) ,
11701049 ( "M1VUXWEZ" ,
11711050 Error :: InvalidChecksum ) ,
11721051 ( "16plkw9" ,
@@ -1248,10 +1127,10 @@ mod tests {
12481127 assert ! ( [ 0u8 , 1 , 2 , 30 , 31 , 255 ] . check_base32_vec( ) . is_err( ) ) ;
12491128
12501129 assert ! ( [ 1u8 , 2 , 3 , 4 ] . check_base32_vec( ) . is_ok( ) ) ;
1251- assert_eq ! (
1130+ assert ! ( matches !(
12521131 [ 30u8 , 31 , 35 , 20 ] . check_base32_vec( ) ,
1253- Err ( Error :: TryFrom ( TryFromIntError :: PosOverflow ) )
1254- )
1132+ Err ( Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidByte ( 35 ) ) )
1133+ ) ) ;
12551134 }
12561135
12571136 #[ test]
@@ -1279,22 +1158,6 @@ mod tests {
12791158 assert_eq ! ( [ 0xffu8 ] . to_base32( ) , [ 0x1f , 0x1c ] . check_base32_vec( ) . unwrap( ) ) ;
12801159 }
12811160
1282- #[ test]
1283- fn reverse_charset ( ) {
1284- fn get_char_value ( c : char ) -> i8 {
1285- let charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" ;
1286- match charset. find ( c. to_ascii_lowercase ( ) ) {
1287- Some ( x) => x as i8 ,
1288- None => -1 ,
1289- }
1290- }
1291-
1292- let expected_rev_charset =
1293- ( 0u8 ..128 ) . map ( |i| get_char_value ( i as char ) ) . collect :: < Vec < _ > > ( ) ;
1294-
1295- assert_eq ! ( & ( CHARSET_REV [ ..] ) , expected_rev_charset. as_slice( ) ) ;
1296- }
1297-
12981161 #[ test]
12991162 #[ cfg( feature = "alloc" ) ]
13001163 fn write_with_checksum ( ) {
0 commit comments