use std::sync::Arc; use super::entity_id::EntityId; use super::state_object::StateObject; use pyo3::{conversion::FromPyObjectOwned, Borrowed, FromPyObject, Py, PyAny, PyErr, Python}; use python_utils::{detach, validate_type_by_name, TypeByNameValidationError}; use snafu::{ResultExt, Snafu}; #[derive(Debug)] pub struct StateMachine(Py); impl<'a, 'py> FromPyObject<'a, 'py> for StateMachine { type Error = TypeByNameValidationError; fn extract(ob: Borrowed<'a, 'py, PyAny>) -> Result { // region: Validation validate_type_by_name(&ob, "StateMachine")?; // endregion: Validation Ok(Self(detach(ob))) } } #[derive(Debug, Clone, Snafu)] pub enum GetStateError { /// couldn't get this state object from the state machine GetStateObjectError { source: Arc }, /// couldn't extract the state as a [`StateObject`] ExtractStateObjectError { source: ExtractStateObjectError }, } impl StateMachine { pub fn get< 'a, 'py, State: FromPyObjectOwned<'py>, Attributes: FromPyObjectOwned<'py>, ContextEvent: FromPyObjectOwned<'py>, >( &'a self, py: Python<'py>, entity_id: EntityId, ) -> Result< Option>, GetStateError< > as FromPyObject<'a, 'py>>::Error, >, > { let args = (entity_id.to_string(),); let state = self .0 .call_method1(py, "get", args) .map_err(Arc::new) .context(GetStateObjectSnafu)?; Ok(state.extract(py).context(ExtractStateObjectSnafu)?) } }