Files
smart-home-in-rust-with-hom…/home-assistant/src/state_machine.rs

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)?)
}
}