serde-bencode icon indicating copy to clipboard operation
serde-bencode copied to clipboard

Tuple structs cannot be deserialized

Open josecelano opened this issue 2 years ago • 0 comments

It seems you can not deserialize a tuple struct like this struct Node(String, i64) from a nested list in encoded format. There are already two tests for this behavior.

   #[test]
    fn deserialization() {
        // todo: you cannot deserialize to the same struct used in serialization.
        // It does not work with a tuple struct `struct Node(String, i64)`
        // instead of a tuple `(String, i64)`.

        #[allow(dead_code)]
        #[derive(PartialEq, Debug, Serialize, Deserialize)]
        struct Torrent {
            info: Info,
            #[serde(default)]
            nodes: Option<Vec<(String, i64)>>,
        }

        #[allow(dead_code)]
        #[derive(PartialEq, Debug, Serialize, Deserialize)]
        struct Info {
            #[serde(default)]
            pub length: Option<i64>,

            #[serde(default)]
            pub name: String,

            #[serde(rename = "piece length")]
            pub piece_length: i64,

            #[serde(default)]
            pub pieces: ByteBuf,
        }

        #[derive(PartialEq, Debug, Serialize, Deserialize)]
        struct Node(String, i64);

        // cspell:disable-next-line
        let b = "d4:infod6:lengthi8e4:name11:minimal.txt12:piece lengthi1e6:pieces1:pe5:nodesll15:188.163.121.224i56711eel14:162.250.131.26i13386eeee";

        let r: Torrent = from_str(b).unwrap();

        assert_eq!(
            r,
            Torrent {
                info: Info {
                    name: "minimal.txt".to_string(),
                    pieces: ByteBuf::from(vec![b'p']),
                    piece_length: 1,
                    length: Some(8),
                },
                nodes: Some(vec![
                    ("188.163.121.224".to_string(), 56711),
                    ("162.250.131.26".to_string(), 13386),
                ]),
            }
        );
    }

Although you can serialize them:

    #[test]
    fn serialization() {
        #[allow(dead_code)]
        #[derive(PartialEq, Debug, Serialize, Deserialize)]
        struct Torrent {
            info: Info,

            #[serde(default)]
            nodes: Option<Vec<Node>>,
        }

        #[allow(dead_code)]
        #[derive(PartialEq, Debug, Serialize, Deserialize)]
        struct Info {
            #[serde(default)]
            pub length: Option<i64>,

            #[serde(default)]
            pub name: String,

            #[serde(rename = "piece length")]
            pub piece_length: i64,

            #[serde(default)]
            pub pieces: ByteBuf,
        }

        #[derive(PartialEq, Debug, Serialize, Deserialize)]
        struct Node(String, i64);

        let torrent = Torrent {
            info: Info {
                name: "minimal.txt".to_string(),
                pieces: ByteBuf::from(vec![b'p']),
                piece_length: 1,
                length: Some(8),
            },
            nodes: Some(vec![
                Node("188.163.121.224".to_string(), 56711),
                Node("162.250.131.26".to_string(), 13386),
            ]),
        };

        // cspell:disable-next-line
        assert_eq!(to_string(&torrent).unwrap(), "d4:infod6:lengthi8e4:name11:minimal.txt12:piece lengthi1e6:pieces1:pe5:nodesll15:188.163.121.224i56711eel14:162.250.131.26i13386eeee");
    }

Both options:

  • nodes: Option<Vec<Node>>, where Node is struct Node(String, i64)
  • nodes: Option<Vec<(String, i64)>>,

produce the same bencoded, but you can only deserialize the second one. The first one gives you only one item in the parent list (one node).

I am still determining if that's a bug. As bencoded format is ordered, there should be no problem assigning the values to the tuple struct fields (0 and 1). The first value should be assigned to the first element in the tuple.

Anyway, ti seems the problem is not even in this package but when the series values are mapped to the final struct (not sure).

josecelano avatar Oct 09 '23 14:10 josecelano