@@ -6,7 +6,9 @@ pub(crate) trait Bech32m<const PREFIX: usize, const DATA: usize> {
66 const HRP : Hrp ;
77 const TYPE : & ' static str ;
88
9- fn decode_bech32m ( s : & str ) -> Result < ( [ Fe32 ; PREFIX ] , [ u8 ; DATA ] ) , Bech32mError > {
9+ type Suffix : Bech32mSuffix ;
10+
11+ fn decode_bech32m ( s : & str ) -> Result < Bech32mPayload < PREFIX , DATA , Self :: Suffix > , Bech32mError > {
1012 let hrp_string = CheckedHrpstring :: new :: < bech32:: Bech32m > ( s)
1113 . context ( bech32m_error:: Decode { ty : Self :: TYPE } ) ?;
1214
@@ -28,8 +30,6 @@ pub(crate) trait Bech32m<const PREFIX: usize, const DATA: usize> {
2830 bech32m_error:: UnsupportedVersion { ty: Self :: TYPE , version } ,
2931 }
3032
31- Self :: validate_padding ( & hrp_string) . context ( bech32m_error:: Padding { ty : Self :: TYPE } ) ?;
32-
3333 let mut prefix = [ Fe32 :: Q ; PREFIX ] ;
3434
3535 for ( actual, fe32) in prefix. iter_mut ( ) . enumerate ( ) {
@@ -42,38 +42,46 @@ pub(crate) trait Bech32m<const PREFIX: usize, const DATA: usize> {
4242
4343 let mut data = [ 0 ; DATA ] ;
4444
45- {
46- let mut bytes = fe32s. fes_to_bytes ( ) ;
47-
48- let mut actual = 0 ;
49- for byte in & mut data {
50- * byte = bytes. next ( ) . context ( bech32m_error:: DataLength {
51- actual,
52- expected : DATA ,
53- ty : Self :: TYPE ,
54- } ) ?;
55- actual += 1 ;
56- }
57-
58- actual += bytes. count ( ) ;
59-
60- ensure ! {
61- actual == DATA ,
62- bech32m_error:: DataLength {
63- actual,
64- expected: DATA ,
65- ty: Self :: TYPE ,
66- } ,
67- }
45+ let mut bytes = fe32s. fes_to_bytes ( ) ;
46+
47+ for ( actual, byte) in data. iter_mut ( ) . enumerate ( ) {
48+ * byte = bytes. next ( ) . context ( bech32m_error:: DataLength {
49+ actual,
50+ expected : DATA ,
51+ ty : Self :: TYPE ,
52+ } ) ?;
6853 }
6954
70- Ok ( ( prefix, data) )
55+ let suffix = Self :: Suffix :: from_bytes ( Self :: TYPE , bytes) ?;
56+
57+ Self :: validate_padding ( & hrp_string) . context ( bech32m_error:: Padding { ty : Self :: TYPE } ) ?;
58+
59+ Ok ( Bech32mPayload {
60+ data,
61+ prefix,
62+ suffix,
63+ } )
7164 }
7265
73- fn encode_bech32m ( f : & mut Formatter , prefix : [ Fe32 ; PREFIX ] , data : [ u8 ; DATA ] ) -> fmt:: Result {
66+ fn encode_bech32m (
67+ f : & mut Formatter ,
68+ payload : Bech32mPayload < PREFIX , DATA , Self :: Suffix > ,
69+ ) -> fmt:: Result {
70+ let Bech32mPayload {
71+ data,
72+ prefix,
73+ suffix,
74+ } = payload;
75+
7476 let chars = prefix
7577 . into_iter ( )
76- . chain ( data. iter ( ) . copied ( ) . bytes_to_fes ( ) )
78+ . chain (
79+ data
80+ . iter ( )
81+ . copied ( )
82+ . chain ( suffix. into_bytes ( ) )
83+ . bytes_to_fes ( ) ,
84+ )
7785 . with_checksum :: < bech32:: Bech32m > ( & Self :: HRP )
7886 . with_witness_version ( VERSION )
7987 . chars ( ) ;
@@ -90,6 +98,10 @@ pub(crate) trait Bech32m<const PREFIX: usize, const DATA: usize> {
9098
9199 fe32s. next ( ) . unwrap ( ) ;
92100
101+ for _ in 0 ..PREFIX {
102+ fe32s. next ( ) . unwrap ( ) ;
103+ }
104+
93105 let Some ( ( i, last) ) = fe32s. enumerate ( ) . last ( ) else {
94106 return Ok ( ( ) ) ;
95107 } ;
@@ -117,11 +129,12 @@ mod tests {
117129 impl Bech32m < 0 , 0 > for EmptyPublicKey {
118130 const HRP : Hrp = Hrp :: parse_unchecked ( "public" ) ;
119131 const TYPE : & ' static str = "public key" ;
132+ type Suffix = ( ) ;
120133 }
121134
122135 impl Display for EmptyPublicKey {
123136 fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
124- Self :: encode_bech32m ( f, [ ] , [ ] )
137+ Self :: encode_bech32m ( f, Bech32mPayload :: from_data ( [ ] ) )
125138 }
126139 }
127140
@@ -130,11 +143,12 @@ mod tests {
130143 impl Bech32m < 0 , 33 > for LongPublicKey {
131144 const HRP : Hrp = Hrp :: parse_unchecked ( "public" ) ;
132145 const TYPE : & ' static str = "public key" ;
146+ type Suffix = ( ) ;
133147 }
134148
135149 impl Display for LongPublicKey {
136150 fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
137- Self :: encode_bech32m ( f, [ ] , [ 0 ; 33 ] )
151+ Self :: encode_bech32m ( f, Bech32mPayload :: from_data ( [ 0 ; 33 ] ) )
138152 }
139153 }
140154
@@ -189,7 +203,7 @@ mod tests {
189203
190204 case (
191205 & LongPublicKey . to_string ( ) ,
192- "expected bech32m public key to have 32 data bytes but found 33 " ,
206+ "expected bech32m public key to have 0 suffix bytes but found 1 " ,
193207 ) ;
194208
195209 let public_key = test:: PUBLIC_KEY . parse :: < PublicKey > ( ) . unwrap ( ) ;
@@ -241,6 +255,7 @@ mod tests {
241255 impl Bech32m < 2 , 0 > for PrefixedType {
242256 const HRP : Hrp = Hrp :: parse_unchecked ( "test" ) ;
243257 const TYPE : & ' static str = "test" ;
258+ type Suffix = ( ) ;
244259 }
245260
246261 let bech32m = [ ]
0 commit comments