Skip to content

Tuple structs cannot be deserialized #37

@josecelano

Description

@josecelano

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions