Skip to content

cleaning up str/bytes and bytesinner/byteslike #2023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 27, 2020
1 change: 1 addition & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pub mod cell;
pub mod float_ops;
pub mod hash;
pub mod rc;
pub mod str;
48 changes: 48 additions & 0 deletions common/src/str.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
pub fn get_chars(s: &str, range: std::ops::Range<usize>) -> &str {
let mut chars = s.chars();
for _ in 0..range.start {
let _ = chars.next();
}
let start = chars.as_str();
for _ in range {
let _ = chars.next();
}
let end = chars.as_str();
&start[..start.len() - end.len()]
}

pub fn zfill(bytes: &[u8], width: usize) -> Vec<u8> {
if width <= bytes.len() {
bytes.to_vec()
} else {
let (sign, s) = match bytes.first() {
Some(_sign @ b'+') | Some(_sign @ b'-') => {
(unsafe { bytes.get_unchecked(..1) }, &bytes[1..])
}
_ => (&b""[..], bytes),
};
let mut filled = Vec::new();
filled.extend_from_slice(sign);
filled.extend(std::iter::repeat(b'0').take(width - bytes.len()));
filled.extend_from_slice(s);
filled
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_get_chars() {
let s = "0123456789";
assert_eq!(get_chars(s, 3..7), "3456");
assert_eq!(get_chars(s, 3..7), &s[3..7]);

let s = "0유니코드 문자열9";
assert_eq!(get_chars(s, 3..7), "코드 문");

let s = "0😀😃😄😁😆😅😂🤣9";
assert_eq!(get_chars(s, 3..7), "😄😁😆😅");
}
}
12 changes: 6 additions & 6 deletions vm/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ mod decl {
use rustpython_parser::parser;

use super::to_ascii;
use crate::byteslike::PyBytesLike;
use crate::exceptions::PyBaseExceptionRef;
use crate::function::{single_or_tuple_any, Args, KwArgs, OptionalArg, PyFuncArgs};
use crate::obj::objbool::{self, IntoPyBool};
use crate::obj::objbyteinner::PyByteInner;
use crate::obj::objbytes::PyBytesRef;
use crate::obj::objcode::PyCodeRef;
use crate::obj::objdict::PyDictRef;
Expand Down Expand Up @@ -554,18 +554,18 @@ mod decl {
}

#[pyfunction]
fn ord(string: Either<PyByteInner, PyStringRef>, vm: &VirtualMachine) -> PyResult<u32> {
fn ord(string: Either<PyBytesLike, PyStringRef>, vm: &VirtualMachine) -> PyResult<u32> {
match string {
Either::A(bytes) => {
let bytes_len = bytes.elements.len();
Either::A(bytes) => bytes.with_ref(|bytes| {
let bytes_len = bytes.len();
if bytes_len != 1 {
return Err(vm.new_type_error(format!(
"ord() expected a character, but string of length {} found",
bytes_len
)));
}
Ok(u32::from(bytes.elements[0]))
}
Ok(u32::from(bytes[0]))
}),
Either::B(string) => {
let string = string.as_str();
let string_len = string.chars().count();
Expand Down
Loading