Skip to content

Commit f437662

Browse files
committed
{str,bytes}.partition into pystr
1 parent deefce4 commit f437662

File tree

5 files changed

+62
-60
lines changed

5 files changed

+62
-60
lines changed

vm/src/obj/objbytearray.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ impl PyByteArray {
432432
#[pymethod(name = "rpartition")]
433433
fn rpartition(&self, sep: PyByteInner, vm: &VirtualMachine) -> PyResult {
434434
let value = self.borrow_value();
435-
let (front, has_mid, back) = value.rpartition(&sep, vm)?;
435+
let (back, has_mid, front) = value.rpartition(&sep, vm)?;
436436
Ok(vm.ctx.new_tuple(vec![
437437
vm.ctx.new_bytearray(front.to_vec()),
438438
vm.ctx

vm/src/obj/objbyteinner.rs

+10-24
Original file line numberDiff line numberDiff line change
@@ -869,37 +869,23 @@ impl PyByteInner {
869869
sub: &PyByteInner,
870870
vm: &VirtualMachine,
871871
) -> PyResult<(Vec<u8>, bool, Vec<u8>)> {
872-
if sub.elements.is_empty() {
873-
return Err(vm.new_value_error("empty separator".to_owned()));
874-
}
875-
876-
let mut sp = self.elements.splitn_str(2, &sub.elements);
877-
let front = sp.next().unwrap().to_vec();
878-
let (has_mid, back) = if let Some(back) = sp.next() {
879-
(true, back.to_vec())
880-
} else {
881-
(false, Vec::new())
882-
};
883-
Ok((front, has_mid, back))
872+
self.elements.py_partition(
873+
&sub.elements,
874+
|| self.elements.splitn_str(2, &sub.elements),
875+
vm,
876+
)
884877
}
885878

886879
pub fn rpartition(
887880
&self,
888881
sub: &PyByteInner,
889882
vm: &VirtualMachine,
890883
) -> PyResult<(Vec<u8>, bool, Vec<u8>)> {
891-
if sub.elements.is_empty() {
892-
return Err(vm.new_value_error("empty separator".to_owned()));
893-
}
894-
895-
let mut sp = self.elements.rsplitn_str(2, &sub.elements);
896-
let back = sp.next().unwrap().to_vec();
897-
let (has_mid, front) = if let Some(front) = sp.next() {
898-
(true, front.to_vec())
899-
} else {
900-
(false, Vec::new())
901-
};
902-
Ok((front, has_mid, back))
884+
self.elements.py_partition(
885+
&sub.elements,
886+
|| self.elements.rsplitn_str(2, &sub.elements),
887+
vm,
888+
)
903889
}
904890

905891
pub fn expandtabs(&self, options: pystr::ExpandTabsArgs) -> Vec<u8> {

vm/src/obj/objbytes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ impl PyBytes {
396396
#[pymethod(name = "rpartition")]
397397
fn rpartition(&self, sep: PyObjectRef, vm: &VirtualMachine) -> PyResult {
398398
let sub = PyByteInner::try_from_object(vm, sep.clone())?;
399-
let (front, has_mid, back) = self.inner.rpartition(&sub, vm)?;
399+
let (back, has_mid, front) = self.inner.rpartition(&sub, vm)?;
400400
Ok(vm.ctx.new_tuple(vec![
401401
vm.ctx.new_bytes(front),
402402
if has_mid {

vm/src/obj/objstr.rs

+26-34
Original file line numberDiff line numberDiff line change
@@ -813,43 +813,35 @@ impl PyString {
813813
}
814814

815815
#[pymethod]
816-
fn partition(&self, sub: PyStringRef, vm: &VirtualMachine) -> PyResult {
817-
if sub.value.is_empty() {
818-
return Err(vm.new_value_error("empty separator".to_owned()));
819-
}
820-
let mut sp = self.value.splitn(2, &sub.value);
821-
let front = sp.next().unwrap();
822-
let elems = if let Some(back) = sp.next() {
823-
[front, &sub.value, back]
824-
} else {
825-
[front, "", ""]
826-
};
827-
Ok(vm.ctx.new_tuple(
828-
elems
829-
.iter()
830-
.map(|&s| vm.ctx.new_str(s.to_owned()))
831-
.collect(),
832-
))
816+
fn partition(&self, sep: PyStringRef, vm: &VirtualMachine) -> PyResult {
817+
let (front, has_mid, back) =
818+
self.value
819+
.py_partition(&sep.value, || self.value.splitn(2, &sep.value), vm)?;
820+
Ok(vm.ctx.new_tuple(vec![
821+
vm.ctx.new_str(front),
822+
if has_mid {
823+
sep.into_object()
824+
} else {
825+
vm.ctx.new_str("")
826+
},
827+
vm.ctx.new_str(back),
828+
]))
833829
}
834830

835831
#[pymethod]
836-
fn rpartition(&self, sub: PyStringRef, vm: &VirtualMachine) -> PyResult {
837-
if sub.value.is_empty() {
838-
return Err(vm.new_value_error("empty separator".to_owned()));
839-
}
840-
let mut sp = self.value.rsplitn(2, &sub.value);
841-
let back = sp.next().unwrap();
842-
let elems = if let Some(front) = sp.next() {
843-
[front, &sub.value, back]
844-
} else {
845-
["", "", back]
846-
};
847-
Ok(vm.ctx.new_tuple(
848-
elems
849-
.iter()
850-
.map(|&s| vm.ctx.new_str(s.to_owned()))
851-
.collect(),
852-
))
832+
fn rpartition(&self, sep: PyStringRef, vm: &VirtualMachine) -> PyResult {
833+
let (back, has_mid, front) =
834+
self.value
835+
.py_partition(&sep.value, || self.value.rsplitn(2, &sep.value), vm)?;
836+
Ok(vm.ctx.new_tuple(vec![
837+
vm.ctx.new_str(front),
838+
if has_mid {
839+
sep.into_object()
840+
} else {
841+
vm.ctx.new_str("")
842+
},
843+
vm.ctx.new_str(back),
844+
]))
853845
}
854846

855847
/// Return `true` if the sequence is ASCII titlecase and the sequence is not

vm/src/obj/pystr.rs

+24
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,30 @@ where
325325
Ok(joined)
326326
}
327327

328+
fn py_partition<'a, F, S>(
329+
&'a self,
330+
sub: &Self,
331+
split: F,
332+
vm: &VirtualMachine,
333+
) -> PyResult<(Self::Container, bool, Self::Container)>
334+
where
335+
F: Fn() -> S,
336+
S: std::iter::Iterator<Item = &'a Self>,
337+
{
338+
if sub.is_empty() {
339+
return Err(vm.new_value_error("empty separator".to_owned()));
340+
}
341+
342+
let mut sp = split();
343+
let front = sp.next().unwrap().to_container();
344+
let (has_mid, back) = if let Some(back) = sp.next() {
345+
(true, back.to_container())
346+
} else {
347+
(false, Self::Container::new())
348+
};
349+
Ok((front, has_mid, back))
350+
}
351+
328352
fn py_removeprefix<FC>(
329353
&self,
330354
prefix: &Self::Container,

0 commit comments

Comments
 (0)