Skip to content

Commit f7170c5

Browse files
committed
Avoid cost in expected case
1 parent 2966488 commit f7170c5

File tree

1 file changed

+14
-26
lines changed

1 file changed

+14
-26
lines changed

src/validators/config.rs

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::borrow::Cow;
22
use std::str::FromStr;
33

4-
use base64::Engine;
4+
use base64::engine::general_purpose::{STANDARD, URL_SAFE};
5+
use base64::{DecodeError, Engine};
56
use pyo3::types::{PyDict, PyString};
67
use pyo3::{intern, prelude::*};
78

@@ -28,31 +29,18 @@ impl ValBytesMode {
2829
pub fn deserialize_string<'py>(self, s: &str) -> Result<EitherBytes<'_, 'py>, ErrorType> {
2930
match self.ser {
3031
BytesMode::Utf8 => Ok(EitherBytes::Cow(Cow::Borrowed(s.as_bytes()))),
31-
BytesMode::Base64 => {
32-
fn decode(input: &str) -> Result<Vec<u8>, ErrorType> {
33-
base64::engine::general_purpose::URL_SAFE.decode(input).map_err(|err| {
34-
ErrorType::BytesInvalidEncoding {
35-
encoding: "base64".to_string(),
36-
encoding_error: err.to_string(),
37-
context: None,
38-
}
39-
})
40-
}
41-
let result = if s.contains(|c| c == '+' || c == '/') {
42-
let replaced: String = s
43-
.chars()
44-
.map(|c| match c {
45-
'+' => '-',
46-
'/' => '_',
47-
_ => c,
48-
})
49-
.collect();
50-
decode(&replaced)
51-
} else {
52-
decode(s)
53-
};
54-
result.map(EitherBytes::from)
55-
}
32+
BytesMode::Base64 => URL_SAFE
33+
.decode(s)
34+
.or_else(|err| match err {
35+
DecodeError::InvalidByte(_, b'/' | b'+') => STANDARD.decode(s),
36+
_ => Err(err),
37+
})
38+
.map(EitherBytes::from)
39+
.map_err(|err| ErrorType::BytesInvalidEncoding {
40+
encoding: "base64".to_string(),
41+
encoding_error: err.to_string(),
42+
context: None,
43+
}),
5644
BytesMode::Hex => match hex::decode(s) {
5745
Ok(vec) => Ok(EitherBytes::from(vec)),
5846
Err(err) => Err(ErrorType::BytesInvalidEncoding {

0 commit comments

Comments
 (0)