use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ValueRef}; use std::{fmt, str}; #[derive( Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, )] pub enum Frequency { Punctual, Monthly, } impl fmt::Display for Frequency { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Frequency::Punctual => write!(f, "Punctual"), Frequency::Monthly => write!(f, "Monthly"), } } } pub struct ParseFrequencyError; impl str::FromStr for Frequency { type Err = ParseFrequencyError; fn from_str(s: &str) -> Result { match s { "Punctual" => Ok(Frequency::Punctual), "Monthly" => Ok(Frequency::Monthly), _ => Err(ParseFrequencyError {}), } } } impl FromSql for Frequency { fn column_result(value: ValueRef<'_>) -> FromSqlResult { match value { ValueRef::Text(text) => match std::str::from_utf8(text) { Ok("Punctual") => Ok(Frequency::Punctual), Ok("Monthly") => Ok(Frequency::Monthly), Ok(str) => Err(FromSqlError::Other( format!("Unknown frequency: {str}").into(), )), Err(err) => Err(FromSqlError::Other(err.into())), }, _ => Err(FromSqlError::InvalidType), } } }