From d90ac76400cbde74722103fb2882024705f6b79d Mon Sep 17 00:00:00 2001 From: konstin Date: Tue, 16 Jul 2019 20:56:34 +0200 Subject: [PATCH] Implement Index for PyBytes --- CHANGELOG.md | 1 + src/types/string.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fafc6040..3f04a7dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * `module` argument to `pyclass` macro. [#499](https://github.com/PyO3/pyo3/pull/499) * `py_run!` macro [#512](https://github.com/PyO3/pyo3/pull/512) * Use existing fields and methods before calling custom __getattr__. [#505](https://github.com/PyO3/pyo3/pull/512) + * `PyBytes` can now be indexed just like `Vec` ### Fixed diff --git a/src/types/string.rs b/src/types/string.rs index 9db81ca1..1fa41883 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -11,16 +11,22 @@ use crate::types::PyAny; use crate::AsPyPointer; use crate::Python; use std::borrow::Cow; +use std::ops::Index; use std::os::raw::c_char; +use std::slice::SliceIndex; use std::str; /// Represents a Python `string`. +/// +/// This type is immutable #[repr(transparent)] pub struct PyString(PyObject); pyobject_native_type!(PyString, ffi::PyUnicode_Type, ffi::PyUnicode_Check); -/// Represents a Python `byte` string. +/// Represents a Python `bytes`. +/// +/// This type is immutable #[repr(transparent)] pub struct PyBytes(PyObject); @@ -120,6 +126,15 @@ impl PyBytes { } } +/// This is the same way [Vec] is indexed +impl> Index for PyBytes { + type Output = I::Output; + + fn index(&self, index: I) -> &Self::Output { + &self.as_bytes()[index] + } +} + /// Converts Rust `str` to Python object. /// See `PyString::new` for details on the conversion. impl ToPyObject for str { @@ -203,7 +218,7 @@ impl<'source> FromPyObject<'source> for String { #[cfg(test)] mod test { - use super::PyString; + use super::{PyBytes, PyString}; use crate::instance::AsPyRef; use crate::object::PyObject; use crate::Python; @@ -261,4 +276,12 @@ mod test { assert!(py_string.to_string().is_ok()); assert_eq!(Cow::Borrowed(s), py_string.to_string().unwrap()); } + + #[test] + fn test_bytes_index() { + let gil = Python::acquire_gil(); + let py = gil.python(); + let bytes = PyBytes::new(py, b"Hello World"); + assert_eq!(bytes[1], b'e'); + } }