@@ -59,78 +59,7 @@ pub mod primitives;
59
59
60
60
#[ cfg( feature = "arrayvec" ) ]
61
61
use 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;
134
63
135
64
/// Interface to write `u5`s into a sink.
136
65
pub trait WriteBase32 {
@@ -306,7 +235,7 @@ write_base_n! { WriteBase32, u5, write_u5 }
306
235
write_base_n ! { WriteBase256 , u8 , write_u8 }
307
236
308
237
#[ cfg( feature = "arrayvec" ) ]
309
- #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
238
+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
310
239
/// Combination of Errors for use with array vec
311
240
pub enum ComboError {
312
241
/// Error from this crate
@@ -712,13 +641,6 @@ fn split_and_decode(s: &str) -> Result<(String, Vec<u5>), Error> {
712
641
let data = raw_data
713
642
. chars ( )
714
643
. 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
-
722
644
if c. is_lowercase ( ) {
723
645
match case {
724
646
Case :: Upper => return Err ( Error :: MixedCase ) ,
@@ -732,15 +654,7 @@ fn split_and_decode(s: &str) -> Result<(String, Vec<u5>), Error> {
732
654
Case :: Upper => { }
733
655
}
734
656
}
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 )
744
658
} )
745
659
. collect :: < Result < Vec < u5 > , Error > > ( ) ?;
746
660
@@ -788,28 +702,11 @@ where
788
702
789
703
// Check data payload
790
704
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
-
798
705
match case {
799
706
Case :: Upper => Err ( Error :: MixedCase ) ?,
800
707
Case :: None | Case :: Lower => { }
801
708
}
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 ) ?) ?;
813
710
}
814
711
815
712
// Ensure checksum
@@ -868,29 +765,11 @@ fn polymod(values: &[u5]) -> u32 {
868
765
/// Human-readable part and data part separator.
869
766
const SEP : char = '1' ;
870
767
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
-
889
768
/// Generator coefficients
890
769
const GEN : [ u32 ; 5 ] = [ 0x3b6a_57b2 , 0x2650_8e6d , 0x1ea1_19fa , 0x3d42_33dd , 0x2a14_62b3 ] ;
891
770
892
771
/// Error types for Bech32 encoding / decoding.
893
- #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
772
+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
894
773
pub enum Error {
895
774
/// String does not contain the separator character.
896
775
MissingSeparator ,
@@ -907,7 +786,7 @@ pub enum Error {
907
786
/// Attempted to convert a value which overflows a `u5`.
908
787
Overflow ,
909
788
/// Conversion to u5 failed.
910
- TryFrom ( TryFromIntError ) ,
789
+ TryFrom ( primitives :: gf32 :: Error ) ,
911
790
}
912
791
913
792
impl From < Infallible > for Error {
@@ -944,8 +823,8 @@ impl std::error::Error for Error {
944
823
}
945
824
}
946
825
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) }
949
828
}
950
829
951
830
/// Error return when `TryFrom<T>` fails for T -> u5 conversion.
@@ -1132,21 +1011,21 @@ mod tests {
1132
1011
( " 1nwldj5" ,
1133
1012
Error :: InvalidChar ( ' ' ) ) ,
1134
1013
( "abc1\u{2192} axkwrx" ,
1135
- Error :: InvalidChar ( '\u{2192}' ) ) ,
1014
+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( '\u{2192}' ) ) ) ,
1136
1015
( "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx" ,
1137
1016
Error :: InvalidLength ) ,
1138
1017
( "pzry9x0s0muk" ,
1139
1018
Error :: MissingSeparator ) ,
1140
1019
( "1pzry9x0s0muk" ,
1141
1020
Error :: InvalidLength ) ,
1142
1021
( "x1b4n0q5v" ,
1143
- Error :: InvalidChar ( 'b' ) ) ,
1022
+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'b' ) ) ) ,
1144
1023
( "ABC1DEFGOH" ,
1145
- Error :: InvalidChar ( 'O' ) ) ,
1024
+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'O' ) ) ) ,
1146
1025
( "li1dgmt3" ,
1147
1026
Error :: InvalidLength ) ,
1148
1027
( "de1lg7wt\u{ff} " ,
1149
- Error :: InvalidChar ( '\u{ff}' ) ) ,
1028
+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( '\u{ff}' ) ) ) ,
1150
1029
( "\u{20} 1xj0phk" ,
1151
1030
Error :: InvalidChar ( '\u{20}' ) ) ,
1152
1031
( "\u{7F} 1g6xzxy" ,
@@ -1158,15 +1037,15 @@ mod tests {
1158
1037
( "1qyrz8wqd2c9m" ,
1159
1038
Error :: InvalidLength ) ,
1160
1039
( "y1b0jsk6g" ,
1161
- Error :: InvalidChar ( 'b' ) ) ,
1040
+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'b' ) ) ) ,
1162
1041
( "lt1igcx5c0" ,
1163
- Error :: InvalidChar ( 'i' ) ) ,
1042
+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'i' ) ) ) ,
1164
1043
( "in1muywd" ,
1165
1044
Error :: InvalidLength ) ,
1166
1045
( "mm1crxm3i" ,
1167
- Error :: InvalidChar ( 'i' ) ) ,
1046
+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'i' ) ) ) ,
1168
1047
( "au1s5cgom" ,
1169
- Error :: InvalidChar ( 'o' ) ) ,
1048
+ Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidChar ( 'o' ) ) ) ,
1170
1049
( "M1VUXWEZ" ,
1171
1050
Error :: InvalidChecksum ) ,
1172
1051
( "16plkw9" ,
@@ -1248,10 +1127,10 @@ mod tests {
1248
1127
assert ! ( [ 0u8 , 1 , 2 , 30 , 31 , 255 ] . check_base32_vec( ) . is_err( ) ) ;
1249
1128
1250
1129
assert ! ( [ 1u8 , 2 , 3 , 4 ] . check_base32_vec( ) . is_ok( ) ) ;
1251
- assert_eq ! (
1130
+ assert ! ( matches !(
1252
1131
[ 30u8 , 31 , 35 , 20 ] . check_base32_vec( ) ,
1253
- Err ( Error :: TryFrom ( TryFromIntError :: PosOverflow ) )
1254
- )
1132
+ Err ( Error :: TryFrom ( primitives :: gf32 :: Error :: InvalidByte ( 35 ) ) )
1133
+ ) ) ;
1255
1134
}
1256
1135
1257
1136
#[ test]
@@ -1279,22 +1158,6 @@ mod tests {
1279
1158
assert_eq ! ( [ 0xffu8 ] . to_base32( ) , [ 0x1f , 0x1c ] . check_base32_vec( ) . unwrap( ) ) ;
1280
1159
}
1281
1160
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
-
1298
1161
#[ test]
1299
1162
#[ cfg( feature = "alloc" ) ]
1300
1163
fn write_with_checksum ( ) {
0 commit comments