@@ -25,15 +25,22 @@ pub(crate) trait Bech32Encode: AsRef<[u8]> + TryFrom<Vec<u8>, Error=ParseError>
25
25
/// Parses a bech32-encoded message into a TLV stream.
26
26
fn from_bech32_str ( s : & str ) -> Result < Self , ParseError > {
27
27
// Offer encoding may be split by '+' followed by optional whitespace.
28
- for chunk in s. split ( '+' ) {
29
- let chunk = chunk. trim_start ( ) ;
30
- if chunk. is_empty ( ) || chunk. contains ( char:: is_whitespace) {
31
- return Err ( ParseError :: InvalidContinuation ) ;
32
- }
33
- }
28
+ let encoded = match s. split ( '+' ) . skip ( 1 ) . next ( ) {
29
+ Some ( _) => {
30
+ for chunk in s. split ( '+' ) {
31
+ let chunk = chunk. trim_start ( ) ;
32
+ if chunk. is_empty ( ) || chunk. contains ( char:: is_whitespace) {
33
+ return Err ( ParseError :: InvalidContinuation ) ;
34
+ }
35
+ }
36
+
37
+ let s = s. chars ( ) . filter ( |c| * c != '+' && !c. is_whitespace ( ) ) . collect :: < String > ( ) ;
38
+ Bech32String :: Owned ( s)
39
+ } ,
40
+ None => Bech32String :: Borrowed ( s) ,
41
+ } ;
34
42
35
- let s = s. chars ( ) . filter ( |c| * c != '+' && !c. is_whitespace ( ) ) . collect :: < String > ( ) ;
36
- let ( hrp, data) = bech32:: decode_without_checksum ( & s) ?;
43
+ let ( hrp, data) = bech32:: decode_without_checksum ( encoded. as_ref ( ) ) ?;
37
44
38
45
if hrp != Self :: BECH32_HRP {
39
46
return Err ( ParseError :: InvalidBech32Hrp ) ;
@@ -52,6 +59,21 @@ pub(crate) trait Bech32Encode: AsRef<[u8]> + TryFrom<Vec<u8>, Error=ParseError>
52
59
}
53
60
}
54
61
62
+ // Used to avoid copying a bech32 string not containing the continuation character (+).
63
+ enum Bech32String < ' a > {
64
+ Borrowed ( & ' a str ) ,
65
+ Owned ( String ) ,
66
+ }
67
+
68
+ impl < ' a > AsRef < str > for Bech32String < ' a > {
69
+ fn as_ref ( & self ) -> & str {
70
+ match self {
71
+ Bech32String :: Borrowed ( s) => s,
72
+ Bech32String :: Owned ( s) => s,
73
+ }
74
+ }
75
+ }
76
+
55
77
/// Error when parsing a bech32 encoded message using [`str::parse`].
56
78
#[ derive( Debug , PartialEq ) ]
57
79
pub enum ParseError {
0 commit comments