Skip to content

Commit c9c9917

Browse files
committed
f - avoid string copy when possible
1 parent b1b283d commit c9c9917

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

lightning/src/offers/parse.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,22 @@ pub(crate) trait Bech32Encode: AsRef<[u8]> + TryFrom<Vec<u8>, Error=ParseError>
2525
/// Parses a bech32-encoded message into a TLV stream.
2626
fn from_bech32_str(s: &str) -> Result<Self, ParseError> {
2727
// 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+
};
3442

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())?;
3744

3845
if hrp != Self::BECH32_HRP {
3946
return Err(ParseError::InvalidBech32Hrp);
@@ -52,6 +59,21 @@ pub(crate) trait Bech32Encode: AsRef<[u8]> + TryFrom<Vec<u8>, Error=ParseError>
5259
}
5360
}
5461

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+
5577
/// Error when parsing a bech32 encoded message using [`str::parse`].
5678
#[derive(Debug, PartialEq)]
5779
pub enum ParseError {

0 commit comments

Comments
 (0)