Skip to content

Commit 066ba2f

Browse files
qingshi163youknowone
authored andcommitted
impl sequence protocol for PyStr
1 parent 1536dd9 commit 066ba2f

File tree

1 file changed

+47
-6
lines changed

1 file changed

+47
-6
lines changed

vm/src/builtins/pystr.rs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ use crate::{
77
anystr::{self, adjust_indices, AnyStr, AnyStrContainer, AnyStrWrapper},
88
format::{FormatSpec, FormatString, FromTemplate},
99
function::{ArgIterable, FuncArgs, IntoPyException, IntoPyObject, OptionalArg, OptionalOption},
10-
protocol::{PyIterReturn, PyMappingMethods},
10+
protocol::{PyIterReturn, PyMappingMethods, PySequenceMethods},
1111
sequence::SequenceOp,
1212
sliceable::SliceableSequenceOp,
1313
types::{
14-
AsMapping, Comparable, Constructor, Hashable, IterNext, IterNextIterable, Iterable,
15-
PyComparisonOp, Unconstructible,
14+
AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, IterNextIterable,
15+
Iterable, PyComparisonOp, Unconstructible,
1616
},
1717
utils::Either,
1818
IdProtocol, PyClassDef, PyClassImpl, PyComparisonValue, PyContext, PyObject, PyObjectRef,
@@ -375,7 +375,7 @@ impl PyStr {
375375

376376
#[pyimpl(
377377
flags(BASETYPE),
378-
with(AsMapping, Hashable, Comparable, Iterable, Constructor)
378+
with(AsMapping, AsSequence, Hashable, Comparable, Iterable, Constructor)
379379
)]
380380
impl PyStr {
381381
#[pymethod(magic)]
@@ -404,9 +404,20 @@ impl PyStr {
404404
!self.bytes.is_empty()
405405
}
406406

407+
fn _contains(&self, needle: &PyObject, vm: &VirtualMachine) -> PyResult<bool> {
408+
if let Some(needle) = needle.payload::<Self>() {
409+
Ok(self.as_str().contains(needle.as_str()))
410+
} else {
411+
Err(vm.new_type_error(format!(
412+
"'in <string>' requires string as left operand, not {}",
413+
needle.class().name()
414+
)))
415+
}
416+
}
417+
407418
#[pymethod(magic)]
408-
fn contains(&self, needle: PyStrRef) -> bool {
409-
self.as_str().contains(needle.as_str())
419+
fn contains(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
420+
self._contains(&needle, vm)
410421
}
411422

412423
#[pymethod(magic)]
@@ -1276,6 +1287,36 @@ impl PyStr {
12761287
};
12771288
}
12781289

1290+
impl AsSequence for PyStr {
1291+
fn as_sequence(
1292+
_zelf: &PyObjectView<Self>,
1293+
_vm: &VirtualMachine,
1294+
) -> std::borrow::Cow<'static, PySequenceMethods> {
1295+
std::borrow::Cow::Borrowed(&Self::SEQUENCE_METHDOS)
1296+
}
1297+
}
1298+
1299+
impl PyStr {
1300+
const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods {
1301+
length: Some(|seq, _vm| Ok(seq.obj_as::<Self>().len())),
1302+
concat: Some(|seq, other, vm| {
1303+
let zelf = seq.obj_as::<Self>();
1304+
Self::add(zelf.to_owned(), other.to_owned(), vm)
1305+
}),
1306+
repeat: Some(|seq, n, vm| {
1307+
let zelf = seq.obj_as::<Self>();
1308+
Self::mul(zelf.to_owned(), n as isize, vm).map(|x| x.into())
1309+
}),
1310+
item: Some(|seq, i, vm| {
1311+
let zelf = seq.obj_as::<Self>();
1312+
zelf.get_item_by_index(vm, i)
1313+
.map(|x| zelf.new_substr(x.to_string()).into_ref(vm).into())
1314+
}),
1315+
contains: Some(|seq, needle, vm| seq.obj_as::<Self>()._contains(needle, vm)),
1316+
..*PySequenceMethods::not_implemented()
1317+
};
1318+
}
1319+
12791320
#[derive(FromArgs)]
12801321
struct EncodeArgs {
12811322
#[pyarg(any, default)]

0 commit comments

Comments
 (0)