@@ -6,7 +6,7 @@ use base256emoji::{Base, Emoji};
66use alloc:: { string:: String , vec:: Vec } ;
77
88macro_rules! derive_base_encoding {
9- ( $( #[ $doc: meta] $type: ident, $encoding: expr; ) * ) => {
9+ ( $( #[ $doc: meta] $type: ident, $encoding: expr, $permissive : expr ; ) * ) => {
1010 $(
1111 #[ $doc]
1212 #[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
@@ -17,16 +17,20 @@ macro_rules! derive_base_encoding {
1717 $encoding. encode( input. as_ref( ) )
1818 }
1919
20- fn decode<I : AsRef <str >>( input: I ) -> Result <Vec <u8 >> {
21- Ok ( $encoding. decode( input. as_ref( ) . as_bytes( ) ) ?)
20+ fn decode<I : AsRef <str >>( input: I , strict: bool ) -> Result <Vec <u8 >> {
21+ if strict {
22+ Ok ( $encoding. decode( input. as_ref( ) . as_bytes( ) ) ?)
23+ } else {
24+ Ok ( $permissive. decode( input. as_ref( ) . as_bytes( ) ) ?)
25+ }
2226 }
2327 }
2428 ) *
2529 } ;
2630}
2731
2832macro_rules! derive_base_x {
29- ( $( #[ $doc: meta] $type: ident, $encoding: expr; ) * ) => {
33+ ( $( #[ $doc: meta] $type: ident, $encoding: expr, $permissive : expr ; ) * ) => {
3034 $(
3135 #[ $doc]
3236 #[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
@@ -37,8 +41,12 @@ macro_rules! derive_base_x {
3741 base_x:: encode( $encoding, input. as_ref( ) )
3842 }
3943
40- fn decode<I : AsRef <str >>( input: I ) -> Result <Vec <u8 >> {
41- Ok ( base_x:: decode( $encoding, input. as_ref( ) ) ?)
44+ fn decode<I : AsRef <str >>( input: I , strict: bool ) -> Result <Vec <u8 >> {
45+ if strict {
46+ Ok ( base_x:: decode( $encoding, input. as_ref( ) ) ?)
47+ } else {
48+ Ok ( base_x:: decode( $permissive, input. as_ref( ) ) ?)
49+ }
4250 }
4351 }
4452 ) *
@@ -50,7 +58,7 @@ pub(crate) trait BaseCodec {
5058 fn encode < I : AsRef < [ u8 ] > > ( input : I ) -> String ;
5159
5260 /// Decode with the given string.
53- fn decode < I : AsRef < str > > ( input : I ) -> Result < Vec < u8 > > ;
61+ fn decode < I : AsRef < str > > ( input : I , strict : bool ) -> Result < Vec < u8 > > ;
5462}
5563
5664/// Identity, 8-bit binary (encoder and decoder keeps data unmodified).
@@ -62,7 +70,7 @@ impl BaseCodec for Identity {
6270 String :: from_utf8 ( input. as_ref ( ) . to_vec ( ) ) . expect ( "input must be valid UTF-8 bytes" )
6371 }
6472
65- fn decode < I : AsRef < str > > ( input : I ) -> Result < Vec < u8 > > {
73+ fn decode < I : AsRef < str > > ( input : I , _strict : bool ) -> Result < Vec < u8 > > {
6674 Ok ( input. as_ref ( ) . as_bytes ( ) . to_vec ( ) )
6775 }
6876}
@@ -76,55 +84,55 @@ impl BaseCodec for Base256Emoji {
7684 Emoji :: encode ( input. as_ref ( ) )
7785 }
7886
79- fn decode < I : AsRef < str > > ( input : I ) -> Result < Vec < u8 > > {
87+ fn decode < I : AsRef < str > > ( input : I , _strict : bool ) -> Result < Vec < u8 > > {
8088 Emoji :: decode ( input. as_ref ( ) ) . map_err ( |e| e. into ( ) )
8189 }
8290}
8391
8492derive_base_encoding ! {
8593 /// Base2 (alphabet: 01).
86- Base2 , encoding:: BASE2 ;
94+ Base2 , encoding:: BASE2 , encoding :: BASE2_PERMISSIVE ;
8795 /// Base8 (alphabet: 01234567).
88- Base8 , encoding:: BASE8 ;
96+ Base8 , encoding:: BASE8 , encoding :: BASE8_PERMISSIVE ;
8997 /// Base16 lower hexadecimal (alphabet: 0123456789abcdef).
90- Base16Lower , encoding:: BASE16_LOWER ;
98+ Base16Lower , encoding:: BASE16_LOWER , encoding :: BASE16_LOWER_PERMISSIVE ;
9199 /// Base16 upper hexadecimal (alphabet: 0123456789ABCDEF).
92- Base16Upper , encoding:: BASE16_UPPER ;
100+ Base16Upper , encoding:: BASE16_UPPER , encoding :: BASE16_UPPER_PERMISSIVE ;
93101 /// Base32, rfc4648 no padding (alphabet: abcdefghijklmnopqrstuvwxyz234567).
94- Base32Lower , encoding:: BASE32_NOPAD_LOWER ;
102+ Base32Lower , encoding:: BASE32_NOPAD_LOWER , encoding :: BASE32_NOPAD_LOWER_PERMISSIVE ;
95103 /// Base32, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567).
96- Base32Upper , encoding:: BASE32_NOPAD_UPPER ;
104+ Base32Upper , encoding:: BASE32_NOPAD_UPPER , encoding :: BASE32_NOPAD_UPPER_PERMISSIVE ;
97105 /// Base32, rfc4648 with padding (alphabet: abcdefghijklmnopqrstuvwxyz234567).
98- Base32PadLower , encoding:: BASE32_PAD_LOWER ;
106+ Base32PadLower , encoding:: BASE32_PAD_LOWER , encoding :: BASE32_PAD_LOWER_PERMISSIVE ;
99107 /// Base32, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567).
100- Base32PadUpper , encoding:: BASE32_PAD_UPPER ;
108+ Base32PadUpper , encoding:: BASE32_PAD_UPPER , encoding :: BASE32_PAD_UPPER_PERMISSIVE ;
101109 /// Base32hex, rfc4648 no padding (alphabet: 0123456789abcdefghijklmnopqrstuv).
102- Base32HexLower , encoding:: BASE32HEX_NOPAD_LOWER ;
110+ Base32HexLower , encoding:: BASE32HEX_NOPAD_LOWER , encoding :: BASE32HEX_NOPAD_LOWER_PERMISSIVE ;
103111 /// Base32hex, rfc4648 no padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUV).
104- Base32HexUpper , encoding:: BASE32HEX_NOPAD_UPPER ;
112+ Base32HexUpper , encoding:: BASE32HEX_NOPAD_UPPER , encoding :: BASE32HEX_NOPAD_UPPER_PERMISSIVE ;
105113 /// Base32hex, rfc4648 with padding (alphabet: 0123456789abcdefghijklmnopqrstuv).
106- Base32HexPadLower , encoding:: BASE32HEX_PAD_LOWER ;
114+ Base32HexPadLower , encoding:: BASE32HEX_PAD_LOWER , encoding :: BASE32HEX_PAD_LOWER_PERMISSIVE ;
107115 /// Base32hex, rfc4648 with padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUV).
108- Base32HexPadUpper , encoding:: BASE32HEX_PAD_UPPER ;
116+ Base32HexPadUpper , encoding:: BASE32HEX_PAD_UPPER , encoding :: BASE32HEX_PAD_UPPER_PERMISSIVE ;
109117 /// z-base-32 (used by Tahoe-LAFS) (alphabet: ybndrfg8ejkmcpqxot1uwisza345h769).
110- Base32Z , encoding:: BASE32Z ;
118+ Base32Z , encoding:: BASE32Z , encoding :: BASE32Z_PERMISSIVE ;
111119 /// Base64, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/).
112- Base64 , encoding:: BASE64_NOPAD ;
120+ Base64 , encoding:: BASE64_NOPAD , encoding :: BASE64_NOPAD_PERMISSIVE ;
113121 /// Base64, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/).
114- Base64Pad , encoding:: BASE64_PAD ;
122+ Base64Pad , encoding:: BASE64_PAD , encoding :: BASE64_PAD_PERMISSIVE ;
115123 /// Base64 url, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_).
116- Base64Url , encoding:: BASE64URL_NOPAD ;
124+ Base64Url , encoding:: BASE64URL_NOPAD , encoding :: BASE64URL_NOPAD_PERMISSIVE ;
117125 /// Base64 url, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_).
118- Base64UrlPad , encoding:: BASE64URL_PAD ;
126+ Base64UrlPad , encoding:: BASE64URL_PAD , encoding :: BASE64URL_PAD_PERMISSIVE ;
119127}
120128
121129derive_base_x ! {
122130 /// Base10 (alphabet: 0123456789).
123- Base10 , encoding:: BASE10 ;
131+ Base10 , encoding:: BASE10 , encoding :: BASE10_PERMISSIVE ;
124132 /// Base58 flicker (alphabet: 123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ).
125- Base58Flickr , encoding:: BASE58_FLICKR ;
133+ Base58Flickr , encoding:: BASE58_FLICKR , encoding :: BASE58_FLICKR_PERMISSIVE ;
126134 /// Base58 bitcoin (alphabet: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz).
127- Base58Btc , encoding:: BASE58_BITCOIN ;
135+ Base58Btc , encoding:: BASE58_BITCOIN , encoding :: BASE58_BITCOIN_PERMISSIVE ;
128136}
129137
130138/// Base36, [0-9a-z] no padding (alphabet: abcdefghijklmnopqrstuvwxyz0123456789).
@@ -136,10 +144,14 @@ impl BaseCodec for Base36Lower {
136144 base_x:: encode ( encoding:: BASE36_LOWER , input. as_ref ( ) )
137145 }
138146
139- fn decode < I : AsRef < str > > ( input : I ) -> Result < Vec < u8 > > {
140- // The input is case insensitive, hence lowercase it
141- let lowercased = input. as_ref ( ) . to_ascii_lowercase ( ) ;
142- Ok ( base_x:: decode ( encoding:: BASE36_LOWER , & lowercased) ?)
147+ fn decode < I : AsRef < str > > ( input : I , strict : bool ) -> Result < Vec < u8 > > {
148+ if strict {
149+ Ok ( base_x:: decode ( encoding:: BASE36_LOWER , input. as_ref ( ) ) ?)
150+ } else {
151+ // The input is case insensitive, hence lowercase it
152+ let lowercased = input. as_ref ( ) . to_ascii_lowercase ( ) ;
153+ Ok ( base_x:: decode ( encoding:: BASE36_LOWER_PERMISSIVE , & lowercased) ?)
154+ }
143155 }
144156}
145157
@@ -152,9 +164,13 @@ impl BaseCodec for Base36Upper {
152164 base_x:: encode ( encoding:: BASE36_UPPER , input. as_ref ( ) )
153165 }
154166
155- fn decode < I : AsRef < str > > ( input : I ) -> Result < Vec < u8 > > {
156- // The input is case insensitive, hence uppercase it
157- let uppercased = input. as_ref ( ) . to_ascii_uppercase ( ) ;
158- Ok ( base_x:: decode ( encoding:: BASE36_UPPER , & uppercased) ?)
167+ fn decode < I : AsRef < str > > ( input : I , strict : bool ) -> Result < Vec < u8 > > {
168+ if strict {
169+ Ok ( base_x:: decode ( encoding:: BASE36_UPPER , input. as_ref ( ) ) ?)
170+ } else {
171+ // The input is case insensitive, hence uppercase it
172+ let uppercased = input. as_ref ( ) . to_ascii_uppercase ( ) ;
173+ Ok ( base_x:: decode ( encoding:: BASE36_UPPER_PERMISSIVE , & uppercased) ?)
174+ }
159175 }
160176}
0 commit comments