feat: FromPyFromStr and ToStrToPy macros YAY
This commit is contained in:
@@ -1,42 +1,39 @@
|
||||
use pyo3::exceptions::{PyTypeError, PyValueError};
|
||||
use pyo3::prelude::*;
|
||||
use snafu::{ResultExt, Snafu};
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
|
||||
use pyo3::FromPyObject;
|
||||
use python_utils::{FromPyFromStr, ToStrToPy};
|
||||
use snafu::Snafu;
|
||||
|
||||
use crate::{entity_id::EntityId, state_object::StateObject};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
// TODO: replace with a derive(PyFromStrLiteral) / #[literal = "state_changed"] once I learn how to make something like that and see about serde or strum integration or inspiration
|
||||
#[derive(Debug, Clone, FromPyFromStr, ToStrToPy)]
|
||||
pub struct Type;
|
||||
|
||||
/// expected a string of value "state_changed", but got {actual}
|
||||
#[derive(Debug, Snafu)]
|
||||
pub enum ExtractTypeError {
|
||||
/// couldn't extract this object as a string
|
||||
ExtractStringError { source: PyErr },
|
||||
|
||||
/// expected a string of value "state_changed", but got {actual}
|
||||
UnexpectedValue { actual: String },
|
||||
pub struct ParseTypeError {
|
||||
actual: String,
|
||||
}
|
||||
|
||||
impl From<ExtractTypeError> for PyErr {
|
||||
fn from(error: ExtractTypeError) -> Self {
|
||||
match &error {
|
||||
ExtractTypeError::ExtractStringError { .. } => PyTypeError::new_err(error.to_string()),
|
||||
ExtractTypeError::UnexpectedValue { .. } => PyValueError::new_err(error.to_string()),
|
||||
impl FromStr for Type {
|
||||
type Err = ParseTypeError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s == "state_changed" {
|
||||
Ok(Self)
|
||||
} else {
|
||||
Err(ParseTypeError {
|
||||
actual: s.to_owned(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: replace with a derive(PyFromStrLiteral) / #[literal = "state_changed"] once I learn how to make something like that and see about serde or strum integration or inspiration
|
||||
impl<'a, 'py> FromPyObject<'a, 'py> for Type {
|
||||
type Error = ExtractTypeError;
|
||||
|
||||
fn extract(ob: Borrowed<'a, 'py, PyAny>) -> Result<Self, Self::Error> {
|
||||
let s = ob.extract::<&str>().context(ExtractStringSnafu)?;
|
||||
|
||||
if s == "state_changed" {
|
||||
Ok(Type)
|
||||
} else {
|
||||
Err(ExtractTypeError::UnexpectedValue { actual: s.into() })
|
||||
}
|
||||
impl Display for Type {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "state_changed")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user