forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtransmute_from.rs
More file actions
29 lines (27 loc) · 978 Bytes
/
transmute_from.rs
File metadata and controls
29 lines (27 loc) · 978 Bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use crate::{
object::{AsObject, PyObject, PyPayload, PyRef, PyResult},
vm::VirtualMachine,
};
/// Marks a type that has the exact same layout as PyObjectRef, e.g. a type that is
/// `repr(transparent)` over PyObjectRef.
///
/// # Safety
/// Can only be implemented for types that are `repr(transparent)` over a PyObjectRef `obj`,
/// and logically valid so long as `check(vm, obj)` returns `Ok(())`
pub unsafe trait TransmuteFromObject: Sized {
fn check(vm: &VirtualMachine, obj: &PyObject) -> PyResult<()>;
}
unsafe impl<T: PyPayload> TransmuteFromObject for PyRef<T> {
fn check(vm: &VirtualMachine, obj: &PyObject) -> PyResult<()> {
let class = T::class(vm);
if obj.fast_isinstance(class) {
if obj.payload_is::<T>() {
Ok(())
} else {
Err(vm.new_downcast_runtime_error(class, obj))
}
} else {
Err(vm.new_downcast_type_error(class, obj))
}
}
}