use serde::{Deserialize, Serialize};
use crate::{impl_default, impl_display, Error, Result};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum PropagateMode {
ChangeOne,
ChangeLater,
ChangeAll,
}
impl PropagateMode {
pub const CHANGE_ONE: &str = "change_one";
pub const CHANGE_LATER: &str = "change_later";
pub const CHANGE_ALL: &str = "change_all";
pub const fn new() -> Self {
Self::ChangeOne
}
pub const fn as_str(&self) -> &'static str {
match self {
Self::ChangeOne => Self::CHANGE_ONE,
Self::ChangeLater => Self::CHANGE_LATER,
Self::ChangeAll => Self::CHANGE_ALL,
}
}
}
impl_default!(PropagateMode);
impl_display!(PropagateMode);
impl From<PropagateMode> for &'static str {
fn from(val: PropagateMode) -> Self {
val.as_str()
}
}
impl TryFrom<&str> for PropagateMode {
type Error = Error;
fn try_from(val: &str) -> Result<Self> {
match val.to_lowercase().as_str() {
Self::CHANGE_ONE => Ok(Self::ChangeOne),
Self::CHANGE_LATER => Ok(Self::ChangeLater),
Self::CHANGE_ALL => Ok(Self::ChangeAll),
_ => Err(Error::invalid_field(
"propagate_mode",
val,
"change_one | change_later | change_all",
)),
}
}
}
impl TryFrom<String> for PropagateMode {
type Error = Error;
fn try_from(val: String) -> Result<Self> {
Self::try_from(val.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_propagate_mode() {
[
(PropagateMode::ChangeOne, PropagateMode::CHANGE_ONE),
(PropagateMode::ChangeLater, PropagateMode::CHANGE_LATER),
(PropagateMode::ChangeAll, PropagateMode::CHANGE_ALL),
]
.into_iter()
.for_each(|(mode, mode_str)| {
assert_eq!(mode.as_str(), mode_str);
let mode_json = format!(r#""{mode_str}""#);
assert_eq!(<&str>::from(mode), mode_str);
assert_eq!(PropagateMode::try_from(mode_str).unwrap(), mode);
assert_eq!(serde_json::to_string(&mode).unwrap(), mode_json);
assert_eq!(
serde_json::from_str::<PropagateMode>(&mode_json).unwrap(),
mode
);
});
}
}