use std::convert::Infallible; use pyo3::prelude::*; use python_utils::{detach, validate_type_by_name, TypeByNameValidationError}; use snafu::{ResultExt, Snafu}; use super::{service_registry::ServiceRegistry, state_machine::StateMachine}; #[derive(Debug)] pub struct HomeAssistant(Py); impl<'a, 'py> FromPyObject<'a, 'py> for HomeAssistant { type Error = TypeByNameValidationError; fn extract(ob: Borrowed<'a, 'py, PyAny>) -> Result { // region: Validation validate_type_by_name(&ob, "HomeAssistant")?; // endregion: Validation Ok(Self(detach(ob))) } } impl<'py> IntoPyObject<'py> for &HomeAssistant { type Target = PyAny; type Output = Bound<'py, Self::Target>; type Error = Infallible; fn into_pyobject(self, py: Python<'py>) -> Result { Ok(self.0.bind(py).to_owned()) } } #[derive(Debug, Snafu)] pub enum GetStatesError { /// couldn't get the `states` attribute on the Home Assistant object GetStatesAttributeError { source: PyErr }, /// couldn't extract the `states` as a [`StateMachine`] ExtractStateMachineError { source: TypeByNameValidationError }, } #[derive(Debug, Snafu)] pub enum GetServicesError { /// couldn't get the `services` attribute on the Home Assistant object GetServicesAttributeError { source: PyErr }, /// couldn't extract the `states` as a [`ServiceRegistry`] ExtractServiceRegistryError { source: TypeByNameValidationError }, } impl HomeAssistant { /// Return the representation pub fn repr(&self, py: Python<'_>) -> Result { let bound = self.0.bind(py); let repr = bound.repr()?; repr.extract() } /// Return if Home Assistant is running. pub fn is_running(&self, py: Python<'_>) -> Result { let is_running = self.0.getattr(py, "is_running")?; is_running.extract(py) } /// Return if Home Assistant is stopping. pub fn is_stopping(&self, py: Python<'_>) -> Result { let is_stopping = self.0.getattr(py, "is_stopping")?; is_stopping.extract(py) } pub fn states(&self, py: Python<'_>) -> Result { let states = self .0 .getattr(py, "states") .context(GetStatesAttributeSnafu)?; states.extract(py).context(ExtractStateMachineSnafu) } pub fn services(&self, py: Python<'_>) -> Result { let services = self .0 .getattr(py, "services") .context(GetServicesAttributeSnafu)?; services.extract(py).context(ExtractServiceRegistrySnafu) } }