use serde::de::{self, IntoDeserializer, Visitor};
use serde::{ser, Deserialize, Serialize};
use std::fmt;
use std::io;
use crate::aclentry::AclEntryKind;
use crate::flag::FlagName;
use crate::perm::PermName;
#[allow(clippy::unnecessary_wraps)]
fn write_enum<T: Serialize>(f: &mut fmt::Formatter, value: T) -> fmt::Result {
let mut serializer = EnumSerializer(f);
value
.serialize(&mut serializer)
.expect("can't serialize value");
Ok(())
}
fn read_enum<'a, T>(s: &'a str) -> Result<T>
where
T: Deserialize<'a>,
{
let mut deserializer = EnumDeserializer(s);
T::deserialize(&mut deserializer)
}
pub fn write_aclentrykind(f: &mut fmt::Formatter, value: AclEntryKind) -> fmt::Result {
write_enum(f, value)
}
pub fn read_aclentrykind(s: &str) -> Result<AclEntryKind> {
read_enum(s)
}
pub fn write_flagname(f: &mut fmt::Formatter, value: FlagName) -> fmt::Result {
write_enum(f, value)
}
pub fn read_flagname(s: &str) -> Result<FlagName> {
read_enum(s)
}
pub fn write_permname(f: &mut fmt::Formatter, value: PermName) -> fmt::Result {
write_enum(f, value)
}
pub fn read_permname(s: &str) -> Result<PermName> {
read_enum(s)
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Error {
Message(String),
NotImplemented,
}
impl ser::Error for Error {
fn custom<T: fmt::Display>(msg: T) -> Self {
Error::Message(msg.to_string())
}
}
impl de::Error for Error {
fn custom<T: fmt::Display>(msg: T) -> Self {
Error::Message(msg.to_string())
}
}
impl From<Error> for io::Error {
fn from(err: Error) -> Self {
io::Error::new(io::ErrorKind::InvalidInput, err)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Message(msg) => write!(f, "{msg}"),
Error::NotImplemented => write!(f, "Not implemented"),
}
}
}
impl std::error::Error for Error {}
type Result<T> = std::result::Result<T, Error>;
struct EnumSerializer<'a, 'b>(&'a mut fmt::Formatter<'b>);
const fn not_implemented<T>() -> Result<T> {
Err(Error::NotImplemented)
}
impl<'a, 'b> ser::Serializer for &mut EnumSerializer<'a, 'b> {
type Ok = ();
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<()> {
self.0.write_str(variant).expect("can't format enum");
Ok(())
}
fn serialize_bool(self, _v: bool) -> Result<()> {
not_implemented()
}
fn serialize_i8(self, _v: i8) -> Result<()> {
not_implemented()
}
fn serialize_i16(self, _v: i16) -> Result<()> {
not_implemented()
}
fn serialize_i32(self, _v: i32) -> Result<()> {
not_implemented()
}
fn serialize_i64(self, _v: i64) -> Result<()> {
not_implemented()
}
fn serialize_u8(self, _v: u8) -> Result<()> {
not_implemented()
}
fn serialize_u16(self, _v: u16) -> Result<()> {
not_implemented()
}
fn serialize_u32(self, _v: u32) -> Result<()> {
not_implemented()
}
fn serialize_u64(self, _v: u64) -> Result<()> {
not_implemented()
}
fn serialize_f32(self, _v: f32) -> Result<()> {
not_implemented()
}
fn serialize_f64(self, _v: f64) -> Result<()> {
not_implemented()
}
fn serialize_char(self, _v: char) -> Result<()> {
not_implemented()
}
fn serialize_str(self, _v: &str) -> Result<()> {
not_implemented()
}
fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
not_implemented()
}
fn serialize_none(self) -> Result<()> {
not_implemented()
}
fn serialize_some<T>(self, _v: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn serialize_unit(self) -> Result<()> {
not_implemented()
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
not_implemented()
}
fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T,
) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
not_implemented()
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
not_implemented()
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
not_implemented()
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
not_implemented()
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
not_implemented()
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
not_implemented()
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
not_implemented()
}
}
impl<'a, 'b> ser::SerializeSeq for &mut EnumSerializer<'a, 'b> {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn end(self) -> Result<()> {
not_implemented()
}
}
impl<'a, 'b> ser::SerializeTuple for &mut EnumSerializer<'a, 'b> {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn end(self) -> Result<()> {
not_implemented()
}
}
impl<'a, 'b> ser::SerializeTupleStruct for &mut EnumSerializer<'a, 'b> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn end(self) -> Result<()> {
not_implemented()
}
}
impl<'a, 'b> ser::SerializeTupleVariant for &mut EnumSerializer<'a, 'b> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn end(self) -> Result<()> {
not_implemented()
}
}
impl<'a, 'b> ser::SerializeMap for &mut EnumSerializer<'a, 'b> {
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, _key: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn serialize_value<T>(&mut self, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn end(self) -> Result<()> {
not_implemented()
}
}
impl<'a, 'b> ser::SerializeStruct for &mut EnumSerializer<'a, 'b> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn end(self) -> Result<()> {
not_implemented()
}
}
impl<'a, 'b> ser::SerializeStructVariant for &mut EnumSerializer<'a, 'b> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
not_implemented()
}
fn end(self) -> Result<()> {
not_implemented()
}
}
#[cfg(test)]
mod serialize_tests {
use super::*;
#[test]
fn test_enum() {
#[derive(Serialize)]
enum E {
Unit,
}
impl fmt::Display for E {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write_enum(f, self)
}
}
let u = E::Unit;
let expected = "Unit";
assert_eq!(format!("{u}"), expected);
}
}
struct EnumDeserializer<'de>(&'de str);
impl<'de, 'a> de::Deserializer<'de> for &'a mut EnumDeserializer<'de> {
type Error = Error;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_bool<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_i32<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_i64<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_u32<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_option<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_newtype_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
_visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
_visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
let value = self.0;
self.0 = "";
visitor.visit_enum(value.into_deserializer())
}
fn deserialize_identifier<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
not_implemented()
}
}
#[cfg(test)]
mod deserialize_tests {
use super::*;
#[test]
fn test_enum() {
#[derive(Deserialize, PartialEq, Debug)]
enum E {
Unit,
}
assert_eq!(E::Unit, read_enum("Unit").unwrap());
let res: Result<E> = read_enum("Unitx");
assert_eq!(
"unknown variant `Unitx`, expected `Unit`",
res.unwrap_err().to_string()
);
}
}