near / borsh-rs

Rust implementation of Binary Object Representation Serializer for Hashing
https://borsh.io/
Apache License 2.0
310 stars 67 forks source link

Dynamically Deserialize with BorshSchema #43

Closed FrankC01 closed 2 years ago

FrankC01 commented 2 years ago

@nearmax

I have a yaml file describing a struct. I would like to create a process that can interpret the yaml declaration and deserialize from a data buffer where the actual struct (or whatever valid and supported Borsh type) has been serialized.

Is there a way, using BorshSchema???, to accomplish this?

Here is what I thought I needed to do, however; the last line throws exception:

    fn test_schema() {
        #[derive(BorshSerialize, Debug)]
        struct A {
            foo: u64,
            bar: String,
        }
        #[derive(BorshSchema, BorshDeserialize, Debug)]
        struct B;
        fn setup_faux_struc() -> Definition {
            Definition::Struct {
                fields: Fields::NamedFields(vec![
                    ("foo".to_string(), "u64".to_string()),
                    ("bar".to_string(), "string".to_string()),
                ]),
            }
        }
        let my_type = setup_faux_struc();
        let mut my_def = HashMap::<String, Definition>::new();
        my_def.insert("B".to_string(), setup_faux_struc());
        B::add_definition("B".to_string(), my_type, &mut my_def);
        // SadDerived::add_definitions_recursively(&mut my_def);
        println!("{:?}", B::declaration());

        let a_with_val = A {
            foo: 1000,
            bar: "goofy".to_string(),
        };
        let b = a_with_val.try_to_vec().unwrap();
        println!("{:?}", b);
        let c = B::try_from_slice(&b).unwrap(); // THROWS EXCEPTION
    }
FrankC01 commented 2 years ago

@nearmax Any input to my question above?

frol commented 2 years ago

@FrankC01 borsh-rs is designed to be static, so it is going to be a completely separate effort to implement a dynamic version of it. It would even make sense to consider using serde and publish it as a new crate.

frol commented 2 years ago
 let c = B::try_from_slice(&b).unwrap(); // THROWS EXCEPTION

What would be the type of variable c in your example? You cannot expect it to be of type B, right? Type B is an empty struct.

FrankC01 commented 2 years ago

So after chatting on Discord I realize that my example was based on a misunderstanding on my part. I'm working on what I needed by parsing the inbound YAML and instantiating necessary constructs which reflect Type and then use standard Borsh deserialize on the input vector

frol commented 2 years ago

@FrankC01 I see. Let's close this issue. Feel free to create a new one once you have clarity on your side