mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
Merge pull request #618 from RustPython/joey/optional-arg-2
Improvements to OptionalArg extractor
This commit is contained in:
2 files changed
+29
-20
No files matched your search
+10
-10
@@ -4,8 +4,8 @@ use super::objtype;
|
||||
use crate::format::{FormatParseError, FormatPart, FormatString};
|
||||
use crate::function::PyRef;
|
||||
use crate::pyobject::{
|
||||
IntoPyObject, OptArg, PyContext, PyFuncArgs, PyIterable, PyObjectPayload, PyObjectPayload2,
|
||||
PyObjectRef, PyResult, TypeProtocol,
|
||||
IntoPyObject, OptionalArg, PyContext, PyFuncArgs, PyIterable, PyObjectPayload,
|
||||
PyObjectPayload2, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
@@ -160,24 +160,24 @@ impl PyStringRef {
|
||||
fn endswith(
|
||||
self,
|
||||
suffix: PyStringRef,
|
||||
start: OptArg<usize>,
|
||||
end: OptArg<usize>,
|
||||
start: OptionalArg<usize>,
|
||||
end: OptionalArg<usize>,
|
||||
_vm: &mut VirtualMachine,
|
||||
) -> bool {
|
||||
let start = start.unwrap_or(0);
|
||||
let end = end.unwrap_or(self.value.len());
|
||||
let start = start.into_option().unwrap_or(0);
|
||||
let end = end.into_option().unwrap_or(self.value.len());
|
||||
self.value[start..end].ends_with(&suffix.value)
|
||||
}
|
||||
|
||||
fn startswith(
|
||||
self,
|
||||
prefix: PyStringRef,
|
||||
start: OptArg<usize>,
|
||||
end: OptArg<usize>,
|
||||
start: OptionalArg<usize>,
|
||||
end: OptionalArg<usize>,
|
||||
_vm: &mut VirtualMachine,
|
||||
) -> bool {
|
||||
let start = start.unwrap_or(0);
|
||||
let end = end.unwrap_or(self.value.len());
|
||||
let start = start.into_option().unwrap_or(0);
|
||||
let end = end.into_option().unwrap_or(self.value.len());
|
||||
self.value[start..end].starts_with(&prefix.value)
|
||||
}
|
||||
|
||||
|
||||
+19
-10
@@ -1223,17 +1223,26 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OptArg<T>(Option<T>);
|
||||
/// An argument that may or may not be provided by the caller.
|
||||
///
|
||||
/// This style of argument is not possible in pure Python.
|
||||
pub enum OptionalArg<T> {
|
||||
Present(T),
|
||||
Missing,
|
||||
}
|
||||
|
||||
impl<T> std::ops::Deref for OptArg<T> {
|
||||
type Target = Option<T>;
|
||||
use self::OptionalArg::*;
|
||||
|
||||
fn deref(&self) -> &Option<T> {
|
||||
&self.0
|
||||
impl<T> OptionalArg<T> {
|
||||
pub fn into_option(self) -> Option<T> {
|
||||
match self {
|
||||
Present(value) => Some(value),
|
||||
Missing => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromArgs for OptArg<T>
|
||||
impl<T> FromArgs for OptionalArg<T>
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
@@ -1248,16 +1257,16 @@ where
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
Ok(OptArg(if let Some(PyArg::Positional(_)) = args.peek() {
|
||||
Ok(if let Some(PyArg::Positional(_)) = args.peek() {
|
||||
let value = if let Some(PyArg::Positional(value)) = args.next() {
|
||||
value
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
Some(T::try_from_object(vm, value)?)
|
||||
Present(T::try_from_object(vm, value)?)
|
||||
} else {
|
||||
None
|
||||
}))
|
||||
Missing
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user