2017-10-06 33 views
1

我需要一个函数,返回一个类型的名称,我有这个函数使用serde,但现在我需要一个替代版本,不需要键入为Deserialize,以便我可以将它用于具有借用成员的结构。使用serde来获取类型的字符串时,类型只是序列化

如何重写此函数以使其在类型为Serialize时有效,但不是Deserialize

#[macro_use] 
extern crate serde; 

#[macro_use] 
extern crate serde_derive; 

use serde::de::{self, Deserialize, Deserializer, Visitor}; 
use std::fmt::{self, Display}; 

fn type_name<'de, D: Deserialize<'de>>() -> &'static str { 
    #[derive(Debug)] 
    struct NoError; 
    impl std::error::Error for NoError { 
     fn description(&self) -> &str { 
      "no error" 
     } 
    } 

    impl Display for NoError { 
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
      write!(f, "NoError") 
     } 
    } 

    impl de::Error for NoError { 
     fn custom<T: Display>(_msg: T) -> Self { 
      NoError 
     } 
    } 

    struct NameDeserializer(Option<&'static str>); 
    impl<'a, 'de> Deserializer<'de> for &'a mut NameDeserializer { 
     type Error = NoError; 
     fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error> 
      where V: Visitor<'de> 
     { 
      Err(NoError) 
     } 
     fn deserialize_unit_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error> 
      where V: Visitor<'de> 
     { 
      self.0 = Some(name); 
      Err(NoError) 
     } 
     fn deserialize_newtype_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error> 
      where V: Visitor<'de> 
     { 
      self.0 = Some(name); 
      Err(NoError) 
     } 
     fn deserialize_tuple_struct<V>(self, name: &'static str, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> 
      where V: Visitor<'de> 
     { 
      self.0 = Some(name); 
      Err(NoError) 
     } 
     fn deserialize_struct<V>(self, name: &'static str, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value, Self::Error> 
      where V: Visitor<'de> 
     { 
      self.0 = Some(name); 
      Err(NoError) 
     } 
     forward_to_deserialize_any! { 
      bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 
      byte_buf option unit seq tuple map enum identifier ignored_any 
     } 
    } 

    let mut deserializer = NameDeserializer(None); 
    let _ = D::deserialize(&mut deserializer); 
    deserializer.0.unwrap() 
} 

#[derive(Serialize, Deserialize)] 
struct Vec2(f32, f32); 

fn main() { 
    println!("{}", type_name::<Vec2>()); 
} 

Here is a playground link.

+0

好像它会是一个更容易编写自己的程序宏并将其应用到你的类型,只要你只需要你控制结构的名称。 – Shepmaster

回答

1

这里是一个Serializer挑出任何结构/单元结构/ NEWTYPE结构/元组结构的名称。


extern crate serde; 

#[macro_use] 
extern crate serde_derive; 

use serde::ser::{self, Serialize, Serializer, SerializeStruct, SerializeTupleStruct, Impossible}; 
use std::fmt::{self, Display}; 

fn type_name<T: Serialize>(t: &T) -> &'static str { 
    #[derive(Debug)] 
    struct NotStruct; 
    type Result<T> = std::result::Result<T, NotStruct>; 
    impl std::error::Error for NotStruct { 
     fn description(&self) -> &str { "not struct" } 
    } 
    impl Display for NotStruct { 
     fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { unimplemented!() } 
    } 
    impl ser::Error for NotStruct { 
     fn custom<T: Display>(_msg: T) -> Self { NotStruct } 
    } 

    struct TypeName; 
    impl Serializer for TypeName { 
     type Ok = &'static str; 
     type Error = NotStruct; 
     type SerializeSeq = Impossible<Self::Ok, Self::Error>; 
     type SerializeTuple = Impossible<Self::Ok, Self::Error>; 
     type SerializeTupleStruct = Struct; 
     type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>; 
     type SerializeMap = Impossible<Self::Ok, Self::Error>; 
     type SerializeStruct = Struct; 
     type SerializeStructVariant = Impossible<Self::Ok, Self::Error>; 
     fn serialize_bool(self, _v: bool) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_i8(self, _v: i8) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_i16(self, _v: i16) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_i32(self, _v: i32) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_i64(self, _v: i64) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_u8(self, _v: u8) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_u16(self, _v: u16) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_u32(self, _v: u32) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_u64(self, _v: u64) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_f32(self, _v: f32) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_f64(self, _v: f64) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_char(self, _v: char) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_str(self, _v: &str) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_none(self) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_unit(self) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> { 
      Ok(name) 
     } 
     fn serialize_unit_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_newtype_struct<T: ?Sized + Serialize>(self, name: &'static str, _value: &T) -> Result<Self::Ok> { 
      Ok(name) 
     } 
     fn serialize_newtype_variant<T: ?Sized + Serialize>(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T) -> Result<Self::Ok> { Err(NotStruct) } 
     fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { Err(NotStruct) } 
     fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { Err(NotStruct) } 
     fn serialize_tuple_struct(self, name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct> { 
      Ok(Struct(name)) 
     } 
     fn serialize_tuple_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeTupleVariant> { Err(NotStruct) } 
     fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { Err(NotStruct) } 
     fn serialize_struct(self, name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { 
      Ok(Struct(name)) 
     } 
     fn serialize_struct_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeStructVariant> { Err(NotStruct) } 
    } 

    struct Struct(&'static str); 
    impl SerializeStruct for Struct { 
     type Ok = &'static str; 
     type Error = NotStruct; 
     fn serialize_field<T: ?Sized + Serialize>(&mut self, _key: &'static str, _value: &T) -> Result<()> { Ok(()) } 
     fn end(self) -> Result<Self::Ok> { 
      Ok(self.0) 
     } 
    } 
    impl SerializeTupleStruct for Struct { 
     type Ok = &'static str; 
     type Error = NotStruct; 
     fn serialize_field<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<()> { Ok(()) } 
     fn end(self) -> Result<Self::Ok> { 
      Ok(self.0) 
     } 
    } 

    t.serialize(TypeName).unwrap() 
} 

#[derive(Serialize)] 
struct Vec2(f32, f32); 

fn main() { 
    println!("{}", type_name(&Vec2(0.0, 0.0))); 
} 
+0

谢谢!顺便说一句,你可以让它为枚举工作吗? :) –

相关问题