Skip to content

Commit 543104d

Browse files
authored
Merge pull request #2023 from youknowone/pystr
cleaning up str/bytes and bytesinner/byteslike
2 parents 3bc7141 + 81d4bc7 commit 543104d

24 files changed

+348
-328
lines changed

common/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ pub mod cell;
44
pub mod float_ops;
55
pub mod hash;
66
pub mod rc;
7+
pub mod str;

common/src/str.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
pub fn get_chars(s: &str, range: std::ops::Range<usize>) -> &str {
2+
let mut chars = s.chars();
3+
for _ in 0..range.start {
4+
let _ = chars.next();
5+
}
6+
let start = chars.as_str();
7+
for _ in range {
8+
let _ = chars.next();
9+
}
10+
let end = chars.as_str();
11+
&start[..start.len() - end.len()]
12+
}
13+
14+
pub fn zfill(bytes: &[u8], width: usize) -> Vec<u8> {
15+
if width <= bytes.len() {
16+
bytes.to_vec()
17+
} else {
18+
let (sign, s) = match bytes.first() {
19+
Some(_sign @ b'+') | Some(_sign @ b'-') => {
20+
(unsafe { bytes.get_unchecked(..1) }, &bytes[1..])
21+
}
22+
_ => (&b""[..], bytes),
23+
};
24+
let mut filled = Vec::new();
25+
filled.extend_from_slice(sign);
26+
filled.extend(std::iter::repeat(b'0').take(width - bytes.len()));
27+
filled.extend_from_slice(s);
28+
filled
29+
}
30+
}
31+
32+
#[cfg(test)]
33+
mod tests {
34+
use super::*;
35+
36+
#[test]
37+
fn test_get_chars() {
38+
let s = "0123456789";
39+
assert_eq!(get_chars(s, 3..7), "3456");
40+
assert_eq!(get_chars(s, 3..7), &s[3..7]);
41+
42+
let s = "0유니코드 문자열9";
43+
assert_eq!(get_chars(s, 3..7), "코드 문");
44+
45+
let s = "0😀😃😄😁😆😅😂🤣9";
46+
assert_eq!(get_chars(s, 3..7), "😄😁😆😅");
47+
}
48+
}

vm/src/builtins.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ mod decl {
1414
use rustpython_parser::parser;
1515

1616
use super::to_ascii;
17+
use crate::byteslike::PyBytesLike;
1718
use crate::exceptions::PyBaseExceptionRef;
1819
use crate::function::{single_or_tuple_any, Args, KwArgs, OptionalArg, PyFuncArgs};
1920
use crate::obj::objbool::{self, IntoPyBool};
20-
use crate::obj::objbyteinner::PyByteInner;
2121
use crate::obj::objbytes::PyBytesRef;
2222
use crate::obj::objcode::PyCodeRef;
2323
use crate::obj::objdict::PyDictRef;
@@ -554,18 +554,18 @@ mod decl {
554554
}
555555

556556
#[pyfunction]
557-
fn ord(string: Either<PyByteInner, PyStringRef>, vm: &VirtualMachine) -> PyResult<u32> {
557+
fn ord(string: Either<PyBytesLike, PyStringRef>, vm: &VirtualMachine) -> PyResult<u32> {
558558
match string {
559-
Either::A(bytes) => {
560-
let bytes_len = bytes.elements.len();
559+
Either::A(bytes) => bytes.with_ref(|bytes| {
560+
let bytes_len = bytes.len();
561561
if bytes_len != 1 {
562562
return Err(vm.new_type_error(format!(
563563
"ord() expected a character, but string of length {} found",
564564
bytes_len
565565
)));
566566
}
567-
Ok(u32::from(bytes.elements[0]))
568-
}
567+
Ok(u32::from(bytes[0]))
568+
}),
569569
Either::B(string) => {
570570
let string = string.as_str();
571571
let string_len = string.chars().count();

0 commit comments

Comments
 (0)