1use qudit_core::ComplexScalar;
2use qudit_core::UnitaryMatrix;
3
4#[derive(Clone)]
5pub enum InstantiationTarget<C: ComplexScalar> {
6 UnitaryMatrix(UnitaryMatrix<C>),
10 }
12
13#[cfg(feature = "python")]
14mod python {
15 use super::InstantiationTarget;
16 use crate::python::PyInstantiationRegistrar;
17 use pyo3::prelude::*;
18 use qudit_core::UnitaryMatrix;
19 use qudit_core::c64;
20
21 #[pyclass(name = "InstantiationTarget")]
22 #[derive(Clone)]
23 pub struct PyInstantiationTarget {
24 inner: InstantiationTarget<c64>,
25 }
26
27 #[pymethods]
28 impl PyInstantiationTarget {
29 #[new]
30 pub fn new<'py>(obj: &Bound<'py, PyAny>) -> PyResult<Self> {
31 if let Ok(unitary) = obj.extract::<UnitaryMatrix<c64>>() {
33 return Ok(Self {
34 inner: InstantiationTarget::UnitaryMatrix(unitary),
35 });
36 }
37
38 Err(pyo3::exceptions::PyTypeError::new_err(
45 "Cannot convert object to InstantiationTarget. Expected UnitaryMatrix.",
46 ))
47 }
48
49 pub fn is_unitary_matrix(&self) -> bool {
50 matches!(self.inner, InstantiationTarget::UnitaryMatrix(_))
51 }
52 }
53
54 impl<'py> IntoPyObject<'py> for InstantiationTarget<c64> {
55 type Target = PyInstantiationTarget;
56 type Output = Bound<'py, PyInstantiationTarget>;
57 type Error = PyErr;
58
59 fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
60 let py_target = PyInstantiationTarget { inner: self };
61 Bound::new(py, py_target)
62 }
63 }
64
65 impl<'a, 'py> FromPyObject<'a, 'py> for InstantiationTarget<c64> {
66 type Error = PyErr;
67
68 fn extract(obj: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> {
69 if let Ok(py_target) = obj.extract::<PyInstantiationTarget>() {
70 return Ok(py_target.inner);
71 }
72
73 let py_target = PyInstantiationTarget::new(&obj)?;
74 Ok(py_target.inner)
75 }
76 }
77
78 fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
80 parent_module.add_class::<PyInstantiationTarget>()?;
81 Ok(())
82 }
83 inventory::submit!(PyInstantiationRegistrar { func: register });
84}