2023-07-28 20:31:04 +01:00
|
|
|
// Define the macro that generates the implementation for the enum
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! implement_boolean_enum {
|
|
|
|
($module_name:ident, $enum_name:ident) => {
|
|
|
|
implement_boolean_enum!($module_name, $enum_name { Yes, No });
|
|
|
|
};
|
|
|
|
($module_name:ident, $enum_name:ident { $yes_variant:ident, $no_variant:ident }) => {
|
|
|
|
pub mod $module_name {
|
|
|
|
use clap::ValueEnum;
|
|
|
|
use strum::{Display, EnumIs, EnumIter, EnumString};
|
|
|
|
|
|
|
|
#[derive(
|
|
|
|
Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Display, EnumIter, EnumString, EnumIs,
|
|
|
|
)]
|
|
|
|
pub enum $enum_name {
|
|
|
|
$yes_variant,
|
|
|
|
$no_variant,
|
|
|
|
}
|
|
|
|
|
|
|
|
mod serde {
|
|
|
|
use serde::de::Visitor;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
|
|
use super::$enum_name;
|
|
|
|
|
|
|
|
impl Serialize for $enum_name {
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
where
|
|
|
|
S: serde::Serializer,
|
|
|
|
{
|
|
|
|
serializer.serialize_bool(matches!(*self, $enum_name::$yes_variant))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct PrivateVisitor;
|
|
|
|
|
|
|
|
impl<'de> Visitor<'de> for PrivateVisitor {
|
|
|
|
type Value = $enum_name;
|
|
|
|
|
|
|
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
formatter.write_str("a boolean value (true/false)")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: serde::de::Error,
|
|
|
|
{
|
|
|
|
if v {
|
|
|
|
Ok($enum_name::$yes_variant)
|
|
|
|
} else {
|
|
|
|
Ok($enum_name::$no_variant)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'de> Deserialize<'de> for $enum_name {
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
where
|
|
|
|
D: serde::Deserializer<'de>,
|
|
|
|
{
|
|
|
|
deserializer.deserialize_bool(PrivateVisitor)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mod from {
|
|
|
|
use super::$enum_name;
|
|
|
|
|
2023-08-24 17:06:19 +01:00
|
|
|
impl From<$enum_name> for bool {
|
|
|
|
fn from(val: $enum_name) -> Self {
|
|
|
|
match val {
|
2023-07-28 20:31:04 +01:00
|
|
|
$enum_name::$yes_variant => true,
|
|
|
|
$enum_name::$no_variant => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::$enum_name;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn deserialize_true() {
|
|
|
|
let input = "true";
|
|
|
|
let val: $enum_name = serde_json::from_str(input).unwrap();
|
|
|
|
assert_eq!($enum_name::$yes_variant, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn deserialize_false() {
|
|
|
|
let input = "false";
|
|
|
|
let val: $enum_name = serde_json::from_str(input).unwrap();
|
|
|
|
assert_eq!($enum_name::$no_variant, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn serialize_true() {
|
|
|
|
let input = $enum_name::$yes_variant;
|
|
|
|
let val = serde_json::to_string(&input).unwrap();
|
|
|
|
assert_eq!(val.as_str(), "true");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn serialize_false() {
|
|
|
|
let input = $enum_name::$no_variant;
|
|
|
|
let val = serde_json::to_string(&input).unwrap();
|
|
|
|
assert_eq!(val.as_str(), "false");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|