-
Notifications
You must be signed in to change notification settings - Fork 1
Bug: nested list deserialization is not working #12
Comments
The test was wrong. I used https://chocobo1.github.io/bencode_online/ to generate the encoded data from the nested lists, but it added an extra dictionary, which is not needed. The new test is the following: #[test]
fn deserialize_to_nested_list_with_mixed_types_in_child_list() {
#[derive(PartialEq, Debug, Deserialize)]
struct Item {
ip: String,
port: i64,
}
let b = "ll15:188.163.121.224i56711eel14:162.250.131.26i13386eee";
let r: Vec<Item> = from_str(b).unwrap();
assert_eq!(
r,
vec![
Item {
ip: "188.163.121.224".to_string(),
port: 56711
},
Item {
ip: "162.250.131.26".to_string(),
port: 13386
}
]
);
} It includes the first item in the list but not the second:
|
The problem could be that it's not possible to deserialize nested lists into a struct. If that's the case, it should return an error, not only the first element. It works if we deserialize into an array of tuples like de following: #[test]
fn deserialize_to_nested_list_tuples() {
let b = "ll15:188.163.121.224i56711eel14:162.250.131.26i13386eee";
let r: Vec<(String, i64)> = from_str(b).unwrap();
assert_eq!(
r,
vec![
("188.163.121.224".to_string(), 56711),
("162.250.131.26".to_string(), 13386)
]
);
} |
I've added more tests for torrent files. One test is passing using the same torrent fixture that is not working here. |
Finally, it seems that you cannot deserialize tuple structs. Check the new test: #[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:
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 assign to the first element in the tuple. |
I'm closing this issue because it's possible to deserialize the nested list. The problem is only when you use tuple structs. I've created a new issue #18, just to define the issue in a more straightforward way now I know the exact problem. |
Relates to: torrust/torrust-index#266
There is a failing test:
The text was updated successfully, but these errors were encountered: