Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuple structs cannot be deserialized #37

Open
josecelano opened this issue Oct 9, 2023 · 0 comments
Open

Tuple structs cannot be deserialized #37

josecelano opened this issue Oct 9, 2023 · 0 comments
Labels

Comments

@josecelano
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant