Skip to content

Commit 1669d52

Browse files
committed
refactor count
1 parent 8bcdbbf commit 1669d52

File tree

2 files changed

+53
-42
lines changed

2 files changed

+53
-42
lines changed

vm/src/obj/objbyteinner.rs

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::obj::objint::PyIntRef;
22
use crate::obj::objslice::PySlice;
33
use crate::pyobject::{PyIterable, PyObjectRef};
4+
use core::ops::Range;
45
use num_bigint::BigInt;
56

67
use crate::function::OptionalArg;
@@ -99,6 +100,53 @@ impl ByteInnerNewOptions {
99100
}
100101
}
101102

103+
#[derive(FromArgs)]
104+
pub struct ByteInnerFindOptions {
105+
#[pyarg(positional_only, optional = false)]
106+
sub: PyObjectRef,
107+
#[pyarg(positional_only, optional = true)]
108+
start: OptionalArg<PyObjectRef>,
109+
#[pyarg(positional_only, optional = true)]
110+
end: OptionalArg<PyObjectRef>,
111+
}
112+
113+
impl ByteInnerFindOptions {
114+
pub fn get_value(
115+
self,
116+
elements: &[u8],
117+
vm: &VirtualMachine,
118+
) -> PyResult<(Vec<u8>, Range<usize>)> {
119+
let sub = match try_as_bytes_like(&self.sub.clone()) {
120+
Some(value) => value,
121+
None => match_class!(self.sub,
122+
i @ PyInt => vec![i.as_bigint().byte_or(vm)?],
123+
obj => {return Err(vm.new_type_error(format!("argument should be integer or bytes-like object, not {}", obj)));}),
124+
};
125+
let start = if let OptionalArg::Present(st) = self.start {
126+
match_class!(st,
127+
i @ PyInt => {Some(i.as_bigint().clone())},
128+
_obj @ PyNone => None,
129+
_=> {return Err(vm.new_type_error("slice indices must be integers or None or have an __index__ method".to_string()));}
130+
)
131+
} else {
132+
None
133+
};
134+
let end = if let OptionalArg::Present(e) = self.end {
135+
match_class!(e,
136+
i @ PyInt => {Some(i.as_bigint().clone())},
137+
_obj @ PyNone => None,
138+
_=> {return Err(vm.new_type_error("slice indices must be integers or None or have an __index__ method".to_string()));}
139+
)
140+
} else {
141+
None
142+
};
143+
144+
let range = elements.to_vec().get_slice_range(&start, &end);
145+
146+
Ok((sub, range))
147+
}
148+
}
149+
102150
impl PyByteInner {
103151
pub fn repr(&self) -> PyResult<String> {
104152
let mut res = String::with_capacity(self.elements.len());
@@ -482,39 +530,8 @@ impl PyByteInner {
482530
Ok(res)
483531
}
484532

485-
pub fn count(
486-
&self,
487-
sub: PyObjectRef,
488-
start: OptionalArg<PyObjectRef>,
489-
end: OptionalArg<PyObjectRef>,
490-
vm: &VirtualMachine,
491-
) -> PyResult<usize> {
492-
let sub = match try_as_bytes_like(&sub) {
493-
Some(value) => value,
494-
None => match_class!(sub,
495-
i @ PyInt => vec![i.as_bigint().byte_or(vm)?],
496-
obj => {return Err(vm.new_type_error(format!("argument should be integer or bytes-like object, not {}", obj)));}),
497-
};
498-
let start = if let OptionalArg::Present(st) = start {
499-
match_class!(st,
500-
i @ PyInt => {Some(i.as_bigint().clone())},
501-
_obj @ PyNone => None,
502-
_=> {return Err(vm.new_type_error("slice indices must be integers or None or have an __index__ method".to_string()));}
503-
)
504-
} else {
505-
None
506-
};
507-
let end = if let OptionalArg::Present(e) = end {
508-
match_class!(e,
509-
i @ PyInt => {Some(i.as_bigint().clone())},
510-
_obj @ PyNone => None,
511-
_=> {return Err(vm.new_type_error("slice indices must be integers or None or have an __index__ method".to_string()));}
512-
)
513-
} else {
514-
None
515-
};
516-
517-
let range = self.elements.get_slice_range(&start, &end);
533+
pub fn count(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult<usize> {
534+
let (sub, range) = options.get_value(&self.elements, vm)?;
518535

519536
if sub.is_empty() {
520537
return Ok(self.len() + 1);

vm/src/obj/objbytes.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::ops::Deref;
77
use crate::function::OptionalArg;
88
use crate::pyobject::{PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue};
99

10-
use super::objbyteinner::{ByteInnerNewOptions, PyByteInner};
10+
use super::objbyteinner::{ByteInnerFindOptions, ByteInnerNewOptions, PyByteInner};
1111
use super::objiter;
1212

1313
use super::objtype::PyClassRef;
@@ -252,14 +252,8 @@ impl PyBytesRef {
252252
}
253253

254254
#[pymethod(name = "count")]
255-
fn count(
256-
self,
257-
sub: PyObjectRef,
258-
start: OptionalArg<PyObjectRef>,
259-
end: OptionalArg<PyObjectRef>,
260-
vm: &VirtualMachine,
261-
) -> PyResult<usize> {
262-
self.inner.count(sub, start, end, vm)
255+
fn count(self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult<usize> {
256+
self.inner.count(options, vm)
263257
}
264258

265259
#[pymethod(name = "join")]

0 commit comments

Comments
 (0)