Skip to content

Nested optional property issue #6

Open
@evilrobot-01

Description

@evilrobot-01

Hi there!

Just trying out your crate and get an issue which seems to be down to optional nested properties, where some of the data appears in the wrong place when unpacking. Details and a sample test below...

image

[dependencies]
jsonm = "0.2.0"
#[cfg(test)]
mod tests {
    use jsonm::packer::{PackOptions, Packer};
    use jsonm::unpacker::Unpacker;
    use serde::{Deserialize, Serialize};
    use std::collections::BTreeMap;

    #[derive(Debug, Deserialize, Serialize)]
    struct Person {
        name: String,
        age: u8,
        address: String,
    }

    impl Person {
        fn new(name: &str, age: u8, address: &str) -> Person {
            Person {
                name: name.to_string(),
                age,
                address: address.to_string(),
            }
        }
    }

    #[derive(Debug, Deserialize, Serialize)]
    struct Record {
        person: Person,
        tag: Option<String>,
    }

    impl Record {
        fn new(person: Person) -> Record {
            Record { person, tag: None }
        }
    }

    #[test]
    // fails as "tag":null becomes "tag": "name 2" through packing to string and then unpacking
    fn test() {
        let records: BTreeMap<u32, Record> = BTreeMap::from([
            (1, Record::new(Person::new("name", 18, "address 1"))),
            (2, Record::new(Person::new("name 2", 60, "address 2"))),
            (3, Record::new(Person::new("name 3", 32, "address 3"))),
            (4, Record::new(Person::new("name 4", 9, "address 2"))),
        ]);
        let serialised = serde_json::to_string(&records).unwrap();

        let packed = pack(records);
        let unpacked: BTreeMap<u32, Record> = unpack(packed);

        assert_eq!(serialised, serde_json::to_string(&unpacked).unwrap())
    }

    fn pack<T: Serialize>(value: T) -> String {
        let mut packer = Packer::new();
        let options = PackOptions::new();
        let value = serde_json::value::to_value(value).unwrap();
        println!("pack input: {value}");
        let packed = packer.pack(&value, &options).unwrap();
        println!("packed: {packed}");
        packed.to_string()
    }

    fn unpack<T: for<'de> Deserialize<'de>>(value: String) -> T {
        println!("unpack input: {value}");
        let packed = serde_json::from_str(&value).unwrap();
        println!("unpacked value: {packed}");
        let mut unpacker = Unpacker::new();
        let unpacked = unpacker.unpack(&packed).unwrap();
        println!("unpacked: {unpacked}");
        let unpacked = serde_json::from_value(unpacked).unwrap();
        unpacked
    }
}

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions