Support conversion between char and PyString
This commit is contained in:
parent
096b0a3ac6
commit
830c68648c
|
@ -174,10 +174,7 @@ pub trait FromPyObject<'source>: Sized {
|
|||
|
||||
/// Identity conversion: allows using existing `PyObject` instances where
|
||||
/// `T: ToPyObject` is expected.
|
||||
impl<'a, T: ?Sized> ToPyObject for &'a T
|
||||
where
|
||||
T: ToPyObject,
|
||||
{
|
||||
impl<'a, T: ?Sized + ToPyObject> ToPyObject for &'a T {
|
||||
#[inline]
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
<T as ToPyObject>::to_object(*self, py)
|
||||
|
|
|
@ -141,6 +141,19 @@ impl ToPyObject for String {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToPyObject for char {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
self.into_py(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPy<PyObject> for char {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
let mut bytes = [0u8; 4];
|
||||
PyString::new(py, self.encode_utf8(&mut bytes)).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPy<PyObject> for String {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
PyString::new(py, &self).into()
|
||||
|
@ -156,7 +169,7 @@ impl<'a> IntoPy<PyObject> for &'a String {
|
|||
|
||||
/// Allows extracting strings from Python objects.
|
||||
/// Accepts Python `str` and `unicode` objects.
|
||||
impl<'source> crate::FromPyObject<'source> for &'source str {
|
||||
impl<'source> FromPyObject<'source> for &'source str {
|
||||
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
||||
<PyString as PyTryFrom>::try_from(ob)?.to_str()
|
||||
}
|
||||
|
@ -172,6 +185,20 @@ impl<'source> FromPyObject<'source> for String {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'source> FromPyObject<'source> for char {
|
||||
fn extract(obj: &'source PyAny) -> PyResult<Self> {
|
||||
let s = PyString::try_from(obj)?.to_str()?;
|
||||
let mut iter = s.chars();
|
||||
if let (Some(ch), None) = (iter.next(), iter.next()) {
|
||||
Ok(ch)
|
||||
} else {
|
||||
Err(crate::exceptions::PyValueError::new_err(format!(
|
||||
"Expected a sting of length 1",
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::PyString;
|
||||
|
@ -198,6 +225,16 @@ mod test {
|
|||
assert_eq!(s, s2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_char() {
|
||||
Python::with_gil(|py| {
|
||||
let ch = '😃';
|
||||
let py_string = ch.to_object(py);
|
||||
let ch2: char = FromPyObject::extract(py_string.as_ref(py)).unwrap();
|
||||
assert_eq!(ch, ch2);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_str_ascii() {
|
||||
let gil = Python::acquire_gil();
|
||||
|
|
Loading…
Reference in a new issue