Convert the Python string data to a Rust string. For UTF-8 and ASCII-only latin-1, returns a borrow into the original string data. For Latin-1, UTF-16 and UTF-32, returns an owned string. Fails with UnicodeDecodeError if the string data isn't valid in its encoding.
(self, py: Python)
| 150 | /// |
| 151 | /// Fails with UnicodeDecodeError if the string data isn't valid in its encoding. |
| 152 | pub fn to_string(self, py: Python) -> PyResult<Cow<'a, str>> { |
| 153 | match self { |
| 154 | PyStringData::Utf8(data) => match str::from_utf8(data) { |
| 155 | Ok(s) => Ok(Cow::Borrowed(s)), |
| 156 | Err(e) => Err(PyErr::from_instance( |
| 157 | py, |
| 158 | exc::UnicodeDecodeError::new_utf8(py, data, e)?, |
| 159 | )), |
| 160 | }, |
| 161 | PyStringData::Latin1(data) => { |
| 162 | if data.is_ascii() { |
| 163 | Ok(Cow::Borrowed(unsafe { str::from_utf8_unchecked(data) })) |
| 164 | } else { |
| 165 | Ok(Cow::Owned(data.iter().map(|&b| b as char).collect())) |
| 166 | } |
| 167 | } |
| 168 | PyStringData::Utf16(data) => { |
| 169 | fn utf16_bytes(input: &[u16]) -> &[u8] { |
| 170 | unsafe { mem::transmute(input) } |
| 171 | } |
| 172 | match String::from_utf16(data) { |
| 173 | Ok(s) => Ok(Cow::Owned(s)), |
| 174 | Err(_) => Err(PyErr::from_instance( |
| 175 | py, |
| 176 | exc::UnicodeDecodeError::new( |
| 177 | py, |
| 178 | cstr!("utf-16"), |
| 179 | utf16_bytes(data), |
| 180 | 0..2 * data.len(), |
| 181 | cstr!("invalid utf-16"), |
| 182 | )?, |
| 183 | )), |
| 184 | } |
| 185 | } |
| 186 | PyStringData::Utf32(data) => { |
| 187 | fn utf32_bytes(input: &[u32]) -> &[u8] { |
| 188 | unsafe { mem::transmute(input) } |
| 189 | } |
| 190 | match data.iter().map(|&u| char::from_u32(u)).collect() { |
| 191 | Some(s) => Ok(Cow::Owned(s)), |
| 192 | None => Err(PyErr::from_instance( |
| 193 | py, |
| 194 | exc::UnicodeDecodeError::new( |
| 195 | py, |
| 196 | cstr!("utf-32"), |
| 197 | utf32_bytes(data), |
| 198 | 0..4 * data.len(), |
| 199 | cstr!("invalid utf-32"), |
| 200 | )?, |
| 201 | )), |
| 202 | } |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | /// Convert the Python string data to a Rust string. |
| 208 | /// |