Merge pull request #618 from RustPython/joey/optional-arg-2

Improvements to OptionalArg extractor
This commit is contained in:
Adam authored and GitHub committed 2019-03-07 08:22:21 +00:00
commit ac6521564f
2 files changed
+29 -20

No files matched your search

+10 -10
View File
@@ -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
View File
@@ -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
})
}
}