代码之家  ›  专栏  ›  技术社区  ›  jka

最小serde反序列化实现是什么样子的?

  •  -2
  • jka  · 技术社区  · 1 年前

    对于最低限度的实现,我希望看到一个程序,其中类型为 String 被反序列化为类型的值 MyStruct :

    struct MyVisitor;
    impl<'de> serde::de::Visitor<'de> for MyVisitor {
        type Value = MyStruct;
    
        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
            formatter.write_str("some string")
        }
    
        fn visit_str<E>(self, _v: &str) -> Result<Self::Value, E>
        where
            E: serde::de::Error,
        {
            /*
    
             Actual deserialization logic will eventually be here.
    
             For now it suffices that all given Strings are deserialized into
             { something: 42 }
    
            */
            return Ok(MyStruct { something: 42 });
        }
    }
    
    #[derive(Debug, serde::Deserialize)]
    struct MyStruct {
        something: u32,
    }
    
    fn main() {
        let my_string: String = "foo".to_string();
    
        let my_visitor = MyVisitor;
    
        /*
    
         TODO:
    
            Deserialize my_string (of type String) into my_value (of type MyStruct)
    
         Maybe something like:
    
            let my_value: MyStruct = MyStruct::deserialize(my_string).unwrap();
    
         or maybe:
    
            let my_value: MyStruct = my_string.into()::deserialize<MyStruct>().unwrap();
    
         or what??
    
         */
        let my_value: MyStruct = which method of what to call here??
    
        println!("{:?}", my_value);
    }
    

    我需要在main的底部调用哪种方法,即在开始的行 let my_value: MyStruct = ?

    0 回复  |  直到 1 年前
        1
  •  1
  •   kmdreko    1 年前

    您似乎希望结构从字符串表示形式反序列化。如果是,您可以实现 Deserialize 手动和依赖 String 的反序列化,然后再进行自己的验证。这样地:

    use serde::de::{Deserialize, Deserializer};
    
    #[derive(Debug)]
    struct MyStruct {
        something: u32,
    }
    
    impl<'de> Deserialize<'de> for MyStruct {
        fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
            let s = String::deserialize(d)?;
            
            // do your deserialization logic here from `s`
            
            Ok(MyStruct { something: 42 })
        }
    }
    

    看到它在 playground 使用serde StrDeserializer 作为示范。