mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Don't double loop over chunks
This commit is contained in:
@@ -123,16 +123,24 @@ impl StrOrChar<'_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn scanstring(s: &str, end: usize, strict: bool) -> Result<(String, usize), DecodeError> {
|
||||
let mut chunks: Vec<StrOrChar> = Vec::new();
|
||||
pub fn scanstring<'a>(
|
||||
s: &'a str,
|
||||
end: usize,
|
||||
strict: bool,
|
||||
) -> Result<(String, usize), DecodeError> {
|
||||
let mut chunks: Vec<StrOrChar<'a>> = Vec::new();
|
||||
let mut output_len = 0usize;
|
||||
let mut push_chunk = |chunk: StrOrChar<'a>| {
|
||||
output_len += chunk.len();
|
||||
chunks.push(chunk);
|
||||
};
|
||||
let mut chunk_start = end;
|
||||
let mut chars = s.char_indices().enumerate().skip(end).peekable();
|
||||
while let Some((char_i, (i, c))) = chars.next() {
|
||||
match c {
|
||||
'"' => {
|
||||
chunks.push(StrOrChar::Str(&s[chunk_start..i]));
|
||||
let len = chunks.iter().map(|x| x.len()).sum();
|
||||
let mut out = String::with_capacity(len);
|
||||
push_chunk(StrOrChar::Str(&s[chunk_start..i]));
|
||||
let mut out = String::with_capacity(output_len);
|
||||
for x in chunks {
|
||||
match x {
|
||||
StrOrChar::Str(s) => out.push_str(s),
|
||||
@@ -158,7 +166,7 @@ pub fn scanstring(s: &str, end: usize, strict: bool) -> Result<(String, usize),
|
||||
't' => "\t",
|
||||
'u' => {
|
||||
let surrogate_err = || DecodeError::new("unpaired surrogate", char_i);
|
||||
chunks.push(StrOrChar::Str(&s[chunk_start..i]));
|
||||
push_chunk(StrOrChar::Str(&s[chunk_start..i]));
|
||||
let mut uni = decode_unicode(&mut chars, char_i)?;
|
||||
chunk_start = char_i + 6;
|
||||
if (0xd800..=0xdbff).contains(&uni) {
|
||||
@@ -184,7 +192,7 @@ pub fn scanstring(s: &str, end: usize, strict: bool) -> Result<(String, usize),
|
||||
}
|
||||
}
|
||||
}
|
||||
chunks.push(StrOrChar::Char(
|
||||
push_chunk(StrOrChar::Char(
|
||||
std::char::from_u32(uni).ok_or_else(surrogate_err)?,
|
||||
));
|
||||
continue;
|
||||
@@ -196,9 +204,9 @@ pub fn scanstring(s: &str, end: usize, strict: bool) -> Result<(String, usize),
|
||||
))
|
||||
}
|
||||
};
|
||||
chunks.push(StrOrChar::Str(&s[chunk_start..i]));
|
||||
push_chunk(StrOrChar::Str(&s[chunk_start..i]));
|
||||
chunk_start = i + 2;
|
||||
chunks.push(StrOrChar::Str(esc));
|
||||
push_chunk(StrOrChar::Str(esc));
|
||||
}
|
||||
'\x00'..='\x1f' if strict => {
|
||||
return Err(DecodeError::new(
|
||||
|
||||
Reference in New Issue
Block a user