extern crate serde;
use bitflags::{
parser::{self, ParseHex, WriteHex},
Flags,
};
use core::{fmt, str};
pub use serde::{
de::{Error, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
struct AsDisplay<'a, B>(pub(crate) &'a B);
impl<'a, B: Flags> fmt::Display for AsDisplay<'a, B>
where
B::Bits: WriteHex,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
parser::to_writer(self.0, f)
}
}
pub fn serialize<B: Flags, S: Serializer>(flags: &B, serializer: S) -> Result<S::Ok, S::Error>
where
B::Bits: WriteHex + Serialize,
{
if serializer.is_human_readable() {
serializer.collect_str(&AsDisplay(flags))
}
else {
flags.bits().serialize(serializer)
}
}
pub fn deserialize<'de, B: Flags, D: Deserializer<'de>>(deserializer: D) -> Result<B, D::Error>
where
B::Bits: ParseHex + Deserialize<'de>,
{
if deserializer.is_human_readable() {
struct FlagsVisitor<B>(core::marker::PhantomData<B>);
impl<'de, B: Flags> Visitor<'de> for FlagsVisitor<B>
where
B::Bits: ParseHex,
{
type Value = B;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a string value of `|` separated flags")
}
fn visit_str<E: Error>(self, flags: &str) -> Result<Self::Value, E> {
parser::from_str(flags).map_err(|e| E::custom(e))
}
}
deserializer.deserialize_str(FlagsVisitor(Default::default()))
} else {
let bits = B::Bits::deserialize(deserializer)?;
Ok(B::from_bits_retain(bits))
}
}