Skip to main content

mtorrent_core/pwp/
testutils.rs

1use super::message::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub enum AnyMessage {
5    Uploader(UploaderMessage),
6    Downloader(DownloaderMessage),
7    Extended((ExtendedMessage, u8)),
8}
9impl From<UploaderMessage> for AnyMessage {
10    fn from(msg: UploaderMessage) -> Self {
11        Self::Uploader(msg)
12    }
13}
14impl From<DownloaderMessage> for AnyMessage {
15    fn from(msg: DownloaderMessage) -> Self {
16        Self::Downloader(msg)
17    }
18}
19impl From<ExtendedMessage> for AnyMessage {
20    fn from(msg: ExtendedMessage) -> Self {
21        let id = match msg {
22            ExtendedMessage::Handshake(_) => 0,
23            ExtendedMessage::PeerExchange(_) => Extension::PeerExchange.local_id(),
24            _ => Extension::Metadata.local_id(),
25        };
26        Self::Extended((msg, id))
27    }
28}
29
30impl AnyMessage {
31    pub fn write_to_buffer(self, buffer: &mut Vec<u8>) {
32        match self {
33            Self::Uploader(msg) => PeerMessage::from(msg).encode(buffer).unwrap(),
34            Self::Downloader(msg) => PeerMessage::from(msg).encode(buffer).unwrap(),
35            Self::Extended(msg) => PeerMessage::from(msg).encode(buffer).unwrap(),
36        }
37    }
38}
39
40/// ```no_run
41/// # use mtorrent_core::msgs;
42/// # use mtorrent_core::pwp::*;
43/// msgs![DownloaderMessage::Interested, DownloaderMessage::NotInterested];
44/// ```
45#[doc(hidden)]
46#[macro_export]
47macro_rules! msgs {
48    ($($arg:expr),+ $(,)? ) => {{
49        let mut buffer = Vec::new();
50        $($crate::pwp::testutils::AnyMessage::write_to_buffer($arg.into(), &mut buffer);)+
51        buffer
52    }};
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_msgs() {
61        let msgs = msgs![
62            DownloaderMessage::Interested,
63            UploaderMessage::Have { piece_index: 42 },
64            ExtendedMessage::MetadataReject { piece: 41 }
65        ];
66
67        let expected = {
68            let extended_content = b"d8:msg_typei2e5:piecei41ee";
69            #[rustfmt::skip]
70            let mut tmp = vec![
71                0, 0, 0, 1,  // len Interested
72                2,           // id Interested
73                0, 0, 0, 5,  // len Have
74                4,           // id Have
75                0, 0, 0, 42, // piece_index
76                0, 0, 0, (extended_content.len() + 2) as u8, // len MetadataReject
77                20, // id Extended
78                1,  // (local) id Metadata
79            ];
80            tmp.extend_from_slice(extended_content);
81            tmp
82        };
83        assert_eq!(msgs, expected);
84    }
85}