Skip to content

Commit eb2bbbd

Browse files
authored
feat: add uuid::NonNilUuid support (#5707)
* feat: add `uuid::NonNillUuid` support * added newsfragment
1 parent d14d76a commit eb2bbbd

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ rust_decimal = { version = "1.15", default-features = false, optional = true }
5757
time = { version = "0.3.38", default-features = false, optional = true }
5858
serde = { version = "1.0", optional = true }
5959
smallvec = { version = "1.0", optional = true }
60-
uuid = { version = "1.11.0", optional = true }
60+
uuid = { version = "1.12.0", optional = true }
6161
lock_api = { version = "0.4", optional = true }
6262
parking_lot = { version = "0.12", optional = true }
6363
iana-time-zone = { version = "0.1", optional = true, features = ["fallback"]}

newsfragments/5707.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for `uuid::NonNilUuid` conversion.

src/conversions/uuid.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![cfg(feature = "uuid")]
22

3-
//! Conversions to and from [uuid](https://docs.rs/uuid/latest/uuid/)'s [`Uuid`] type.
3+
//! Conversions to and from [uuid](https://docs.rs/uuid/latest/uuid/)'s [`Uuid`] and [`NonNilUuid`] types.
44
//!
55
//! This is useful for converting Python's uuid.UUID into and from a native Rust type.
66
//!
@@ -63,10 +63,10 @@
6363
//! returned_uuid = get_uuid(py_uuid)
6464
//! assert py_uuid == returned_uuid
6565
//! ```
66-
use uuid::Uuid;
66+
use uuid::{NonNilUuid, Uuid};
6767

6868
use crate::conversion::IntoPyObject;
69-
use crate::exceptions::PyTypeError;
69+
use crate::exceptions::{PyTypeError, PyValueError};
7070
use crate::instance::Bound;
7171
use crate::sync::PyOnceLock;
7272
use crate::types::any::PyAnyMethods;
@@ -116,6 +116,35 @@ impl<'py> IntoPyObject<'py> for &Uuid {
116116
}
117117
}
118118

119+
impl FromPyObject<'_, '_> for NonNilUuid {
120+
type Error = PyErr;
121+
122+
fn extract(obj: Borrowed<'_, '_, PyAny>) -> PyResult<Self> {
123+
let uuid: Uuid = obj.extract()?;
124+
NonNilUuid::new(uuid).ok_or_else(|| PyValueError::new_err("UUID is nil"))
125+
}
126+
}
127+
128+
impl<'py> IntoPyObject<'py> for NonNilUuid {
129+
type Target = PyAny;
130+
type Output = Bound<'py, Self::Target>;
131+
type Error = PyErr;
132+
133+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
134+
Uuid::from(self).into_pyobject(py)
135+
}
136+
}
137+
138+
impl<'py> IntoPyObject<'py> for &NonNilUuid {
139+
type Target = PyAny;
140+
type Output = Bound<'py, Self::Target>;
141+
type Error = PyErr;
142+
143+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
144+
(*self).into_pyobject(py)
145+
}
146+
}
147+
119148
#[cfg(test)]
120149
mod tests {
121150
use super::*;
@@ -183,4 +212,19 @@ mod tests {
183212
Uuid::parse_str("a6cc5730-2261-11ee-9c43-2eb5a363657c").unwrap(),
184213
"a6cc5730-2261-11ee-9c43-2eb5a363657c"
185214
);
215+
216+
#[test]
217+
fn test_non_nil_uuid() {
218+
Python::attach(|py| {
219+
let rs_uuid = NonNilUuid::new(Uuid::max()).unwrap();
220+
let py_uuid = rs_uuid.into_pyobject(py).unwrap();
221+
222+
let extract_uuid: NonNilUuid = py_uuid.extract().unwrap();
223+
assert_eq!(extract_uuid, rs_uuid);
224+
225+
let nil_uuid = Uuid::nil().into_pyobject(py).unwrap();
226+
let extract_nil: PyResult<NonNilUuid> = nil_uuid.extract();
227+
assert!(extract_nil.is_err());
228+
})
229+
}
186230
}

0 commit comments

Comments
 (0)