Skip to content

Commit 3562f0c

Browse files
committed
add uuid serializer
1 parent 9f7e356 commit 3562f0c

File tree

6 files changed

+84
-5
lines changed

6 files changed

+84
-5
lines changed

src/input/input_abstract.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use super::datetime::{EitherDate, EitherDateTime, EitherTime, EitherTimedelta};
1010
use super::return_enums::{EitherBytes, EitherString};
1111
use super::{GenericArguments, GenericCollection, GenericIterator, GenericMapping, JsonInput};
1212

13-
#[derive(Debug)]
1413
pub enum InputType {
1514
Python,
1615
Json,

src/serializers/shared.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ combined_serializer! {
125125
Model: super::type_serializers::model::ModelSerializer;
126126
Url: super::type_serializers::url::UrlSerializer;
127127
MultiHostUrl: super::type_serializers::url::MultiHostUrlSerializer;
128+
Uuid: super::type_serializers::uuid::UuidSerializer;
128129
Any: super::type_serializers::any::AnySerializer;
129130
Format: super::type_serializers::format::FormatSerializer;
130131
ToString: super::type_serializers::format::ToStringSerializer;

src/serializers/type_serializers/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub mod tuple;
2121
pub mod typed_dict;
2222
pub mod union;
2323
pub mod url;
24+
pub mod uuid;
2425
pub mod with_default;
2526

2627
pub(self) use super::computed_fields::ComputedFields;
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
use std::borrow::Cow;
2+
3+
use pyo3::prelude::*;
4+
use pyo3::types::PyDict;
5+
6+
use crate::definitions::DefinitionsBuilder;
7+
use crate::uuid::PyUuid;
8+
9+
use super::{
10+
infer_json_key, infer_serialize, infer_to_python, BuildSerializer, CombinedSerializer, Extra, SerMode,
11+
TypeSerializer,
12+
};
13+
14+
#[derive(Debug, Clone)]
15+
pub struct UuidSerializer;
16+
17+
impl BuildSerializer for UuidSerializer {
18+
const EXPECTED_TYPE: &'static str = "uuid";
19+
20+
fn build(
21+
_schema: &PyDict,
22+
_config: Option<&PyDict>,
23+
_definitions: &mut DefinitionsBuilder<CombinedSerializer>,
24+
) -> PyResult<CombinedSerializer> {
25+
Ok(Self {}.into())
26+
}
27+
}
28+
29+
impl TypeSerializer for UuidSerializer {
30+
fn to_python(
31+
&self,
32+
value: &PyAny,
33+
include: Option<&PyAny>,
34+
exclude: Option<&PyAny>,
35+
extra: &Extra,
36+
) -> PyResult<PyObject> {
37+
let py = value.py();
38+
match value.extract::<PyUuid>() {
39+
Ok(py_uuid) => match extra.mode {
40+
SerMode::Json => Ok(py_uuid.__str__().into_py(py)),
41+
_ => Ok(value.into_py(py)),
42+
},
43+
Err(_) => {
44+
extra.warnings.on_fallback_py(self.get_name(), value, extra)?;
45+
infer_to_python(value, include, exclude, extra)
46+
}
47+
}
48+
}
49+
50+
fn json_key<'py>(&self, key: &'py PyAny, extra: &Extra) -> PyResult<Cow<'py, str>> {
51+
match key.extract::<PyUuid>() {
52+
Ok(py_uuid) => Ok(Cow::Owned(py_uuid.__str__())),
53+
Err(_) => {
54+
extra.warnings.on_fallback_py(self.get_name(), key, extra)?;
55+
infer_json_key(key, extra)
56+
}
57+
}
58+
}
59+
60+
fn serde_serialize<S: serde::ser::Serializer>(
61+
&self,
62+
value: &PyAny,
63+
serializer: S,
64+
include: Option<&PyAny>,
65+
exclude: Option<&PyAny>,
66+
extra: &Extra,
67+
) -> Result<S::Ok, S::Error> {
68+
match value.extract::<PyUuid>() {
69+
Ok(py_uuid) => serializer.serialize_str(&py_uuid.__str__()),
70+
Err(_) => {
71+
extra.warnings.on_fallback_ser::<S>(self.get_name(), value, extra)?;
72+
infer_serialize(value, serializer, include, exclude, extra)
73+
}
74+
}
75+
}
76+
77+
fn get_name(&self) -> &str {
78+
Self::EXPECTED_TYPE
79+
}
80+
}

src/uuid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl PyUuid {
8585
}
8686

8787
fn __bool__(&self) -> bool {
88-
true // an empty string is not a valid UUID
88+
true
8989
}
9090

9191
pub fn __deepcopy__(&self, py: Python, _memo: &PyDict) -> Py<PyAny> {

tests/test_schema_functions.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ def args(*args, **kwargs):
219219
),
220220
(core_schema.json_schema, args({'type': 'int'}), {'type': 'json', 'schema': {'type': 'int'}}),
221221
(core_schema.url_schema, args(), {'type': 'url'}),
222+
(core_schema.uuid_schema, args(), {'type': 'uuid'}),
222223
(core_schema.multi_host_url_schema, args(), {'type': 'multi-host-url'}),
223224
(
224225
core_schema.lax_or_strict_schema,
@@ -279,9 +280,6 @@ def test_all_schema_functions_used():
279280
types_used.remove('typed-dict-field')
280281
types_used.remove('model-field')
281282

282-
# TODO(martinabeleda): use this schema
283-
all_types.remove('uuid')
284-
285283
assert all_types == types_used
286284

287285

0 commit comments

Comments
 (0)