59 lines
1.7 KiB
Rust
59 lines
1.7 KiB
Rust
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<PyAny>);
|
|
|
|
impl<'a, 'py> FromPyObject<'a, 'py> for StateMachine {
|
|
type Error = TypeByNameValidationError;
|
|
|
|
fn extract(ob: Borrowed<'a, 'py, PyAny>) -> Result<Self, Self::Error> {
|
|
// region: Validation
|
|
validate_type_by_name(&ob, "StateMachine")?;
|
|
// endregion: Validation
|
|
|
|
Ok(Self(detach(ob)))
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Snafu)]
|
|
pub enum GetStateError<ExtractStateObjectError: 'static + snafu::Error> {
|
|
/// couldn't get this state object from the state machine
|
|
GetStateObjectError { source: Arc<PyErr> },
|
|
|
|
/// 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<StateObject<State, Attributes, ContextEvent>>,
|
|
GetStateError<
|
|
<Option<StateObject<State, Attributes, ContextEvent>> 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)?)
|
|
}
|
|
}
|