Skip to content

Commit 0535d7a

Browse files
committed
unify pystr py_pad
1 parent 4ab0524 commit 0535d7a

File tree

3 files changed

+38
-20
lines changed

3 files changed

+38
-20
lines changed

vm/src/obj/objbyteinner.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,12 @@ const ASCII_WHITESPACES: [u8; 6] = [0x20, 0x09, 0x0a, 0x0c, 0x0d, 0x0b];
12461246

12471247
impl<'s> PyCommonString<'s, u8> for [u8] {
12481248
type Container = Vec<u8>;
1249-
type CharIter = std::iter::Map<std::slice::Iter<'s, u8>, fn(&u8) -> char>;
1249+
type CharIter = bstr::Chars<'s>;
1250+
type ElementIter = std::iter::Copied<std::slice::Iter<'s, u8>>;
1251+
1252+
fn element_bytes_len(_: u8) -> usize {
1253+
1
1254+
}
12501255

12511256
fn to_container(&self) -> Self::Container {
12521257
self.to_vec()
@@ -1257,7 +1262,11 @@ impl<'s> PyCommonString<'s, u8> for [u8] {
12571262
}
12581263

12591264
fn chars(&'s self) -> Self::CharIter {
1260-
self.iter().map(|c| *c as char)
1265+
bstr::ByteSlice::chars(self)
1266+
}
1267+
1268+
fn elements(&'s self) -> Self::ElementIter {
1269+
self.iter().copied()
12611270
}
12621271

12631272
fn get_bytes<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self {
@@ -1325,12 +1334,4 @@ impl<'s> PyCommonString<'s, u8> for [u8] {
13251334
}
13261335
splited
13271336
}
1328-
1329-
fn py_pad(&self, left: usize, right: usize, fill: u8) -> Self::Container {
1330-
let mut u = Vec::with_capacity(left + self.len() + right);
1331-
u.extend(std::iter::repeat(fill).take(left));
1332-
u.extend_from_slice(self);
1333-
u.extend(std::iter::repeat(fill).take(right));
1334-
u
1335-
}
13361337
}

vm/src/obj/objstr.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,11 @@ impl PyCommonStringContainer<str> for String {
17141714
impl<'s> PyCommonString<'s, char> for str {
17151715
type Container = String;
17161716
type CharIter = std::str::Chars<'s>;
1717+
type ElementIter = std::str::Chars<'s>;
1718+
1719+
fn element_bytes_len(c: char) -> usize {
1720+
c.len_utf8()
1721+
}
17171722

17181723
fn to_container(&self) -> Self::Container {
17191724
self.to_owned()
@@ -1727,6 +1732,10 @@ impl<'s> PyCommonString<'s, char> for str {
17271732
str::chars(self)
17281733
}
17291734

1735+
fn elements(&'s self) -> Self::ElementIter {
1736+
str::chars(self)
1737+
}
1738+
17301739
fn get_bytes<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self {
17311740
&self[range]
17321741
}
@@ -1807,12 +1816,4 @@ impl<'s> PyCommonString<'s, char> for str {
18071816
}
18081817
splited
18091818
}
1810-
1811-
fn py_pad(&self, left: usize, right: usize, fill: char) -> Self::Container {
1812-
let mut u = String::with_capacity((left + right) * fill.len_utf8() + self.len());
1813-
u.extend(std::iter::repeat(fill).take(left));
1814-
u.push_str(self);
1815-
u.extend(std::iter::repeat(fill).take(right));
1816-
u
1817-
}
18181819
}

vm/src/obj/pystr.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub struct SplitArgs<'a, T, S, E>
99
where
1010
T: TryFromObject + PyCommonStringWrapper<S>,
1111
S: ?Sized + PyCommonString<'a, E>,
12+
E: Copy,
1213
{
1314
#[pyarg(positional_or_keyword, default = "None")]
1415
sep: Option<T>,
@@ -22,6 +23,7 @@ impl<'a, T, S, E> SplitArgs<'a, T, S, E>
2223
where
2324
T: TryFromObject + PyCommonStringWrapper<S>,
2425
S: ?Sized + PyCommonString<'a, E>,
26+
E: Copy,
2527
{
2628
pub fn get_value(self, vm: &VirtualMachine) -> PyResult<(Option<T>, isize)> {
2729
let sep = if let Some(s) = self.sep {
@@ -136,16 +138,22 @@ where
136138

137139
pub trait PyCommonString<'s, E>
138140
where
141+
E: Copy,
139142
Self: 's,
140-
Self::Container: PyCommonStringContainer<Self>,
143+
Self::Container: PyCommonStringContainer<Self> + std::iter::Extend<E>,
141144
Self::CharIter: 's + std::iter::Iterator<Item = char>,
145+
Self::ElementIter: 's + std::iter::Iterator<Item = E>,
142146
{
143147
type Container;
144148
type CharIter;
149+
type ElementIter;
150+
151+
fn element_bytes_len(c: E) -> usize;
145152

146153
fn to_container(&self) -> Self::Container;
147154
fn as_bytes(&self) -> &[u8];
148155
fn chars(&'s self) -> Self::CharIter;
156+
fn elements(&'s self) -> Self::ElementIter;
149157
fn get_bytes<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self;
150158
// FIXME: get_chars is expensive for str
151159
fn get_chars<'a>(&'a self, range: std::ops::Range<usize>) -> &'a Self;
@@ -273,7 +281,15 @@ where
273281
}
274282
}
275283

276-
fn py_pad(&self, left: usize, right: usize, fillchar: E) -> Self::Container;
284+
fn py_pad(&self, left: usize, right: usize, fillchar: E) -> Self::Container {
285+
let mut u = Self::Container::with_capacity(
286+
(left + right) * Self::element_bytes_len(fillchar) + self.bytes_len(),
287+
);
288+
u.extend(std::iter::repeat(fillchar).take(left));
289+
u.push_str(self);
290+
u.extend(std::iter::repeat(fillchar).take(right));
291+
u
292+
}
277293

278294
fn py_center(&self, width: usize, fillchar: E) -> Self::Container {
279295
let marg = width - self.chars_len();

0 commit comments

Comments
 (0)