Skip to content

Commit 025998c

Browse files
committed
refactor: parse bytes
1 parent 98f4a4a commit 025998c

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

src/input/return_enums.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,13 @@ impl<'a> From<&'a PyBytes> for EitherBytes<'a> {
809809
}
810810

811811
impl<'a> EitherBytes<'a> {
812+
pub fn as_slice(&'a self) -> &[u8] {
813+
match self {
814+
EitherBytes::Cow(bytes) => bytes,
815+
EitherBytes::Py(py_bytes) => py_bytes.as_bytes(),
816+
}
817+
}
818+
812819
pub fn len(&'a self) -> PyResult<usize> {
813820
match self {
814821
EitherBytes::Cow(bytes) => Ok(bytes.len()),

src/validators/uuid.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use std::str::from_utf8;
2+
13
use pyo3::intern;
24
use pyo3::prelude::*;
35
use pyo3::sync::GILOnceCell;
4-
use pyo3::types::PyBytes;
56
use pyo3::types::{PyDict, PyType};
67
use uuid::Uuid;
78

@@ -109,7 +110,7 @@ impl Validator for UuidValidator {
109110
input,
110111
))
111112
} else {
112-
let uuid = self.get_uuid(py, input)?;
113+
let uuid = self.get_uuid(input)?;
113114
self.create_py_uuid(py, class, &uuid)
114115
}
115116
}
@@ -132,7 +133,7 @@ impl Validator for UuidValidator {
132133
}
133134

134135
impl UuidValidator {
135-
fn get_uuid<'s, 'data>(&'s self, py: Python<'data>, input: &'data impl Input<'data>) -> ValResult<'data, Uuid> {
136+
fn get_uuid<'s, 'data>(&'s self, input: &'data impl Input<'data>) -> ValResult<'data, Uuid> {
136137
let uuid = match input.exact_str().ok() {
137138
Some(either_string) => {
138139
let cow = either_string.as_cow()?;
@@ -144,10 +145,17 @@ impl UuidValidator {
144145
let either_bytes = input
145146
.validate_bytes(true)
146147
.map_err(|_| ValError::new(ErrorType::UuidType, input))?;
147-
let py_object = either_bytes.into_py(py);
148-
let py_bytes = py_object.downcast::<PyBytes>(py)?;
149-
Uuid::from_slice(py_bytes.as_bytes())
150-
.map_err(|e| ValError::new(ErrorType::UuidParsing { error: e.to_string() }, input))?
148+
let bytes_slice = either_bytes.as_slice();
149+
'parse: {
150+
// Try parsing as utf8, but don't care if it fails
151+
if let Ok(utf8_str) = from_utf8(bytes_slice) {
152+
if let Ok(uuid) = Uuid::parse_str(utf8_str) {
153+
break 'parse uuid;
154+
}
155+
}
156+
Uuid::from_slice(bytes_slice)
157+
.map_err(|e| ValError::new(ErrorType::UuidParsing { error: e.to_string() }, input))?
158+
}
151159
}
152160
};
153161

tests/validators/test_uuid.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
('c0a8f9a8-aa5e-482b-a067-9cb3a51f5c11', UUID('c0a8f9a8-aa5e-482b-a067-9cb3a51f5c11')),
2626
(b'\x12\x34\x56\x78' * 4, UUID('12345678-1234-5678-1234-567812345678')),
2727
(b'\x00\x00\x00\x00' * 4, UUID('00000000-0000-0000-0000-000000000000')),
28+
(b'ebcdab58-6eb8-46fb-a190-d07a33e9eac8', UUID('ebcdab58-6eb8-46fb-a190-d07a33e9eac8')),
2829
(UUID('12345678-1234-5678-1234-567812345678'), UUID('12345678-1234-5678-1234-567812345678')),
2930
(UUID('550e8400-e29b-41d4-a716-446655440000'), UUID('550e8400-e29b-41d4-a716-446655440000')),
3031
# Invalid UUIDs

0 commit comments

Comments
 (0)