1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! Contains main [Torrent] structure used as a "key" to interact with other parts
//! of torro

mod impl_bencode;
pub use impl_bencode::*;

/// Represents the overall torrent directory structure for a given [Torrent]
///
/// This merges the [BEP0003](https://www.bittorrent.org/beps/bep_0003.html) spec
/// of either a single `length` for a file given or a list of dictionaries into
/// this singular enum for easier comprehension
///
/// ## Documentation sourcing
///
/// All "BitTorrent Description" headings are taken from
/// [BEP0003](https://www.bittorrent.org/beps/bep_0003.html) and is subject to
/// change, like any moving standard. This documentation is based off of version
/// `0e08ddf84d8d3bf101cdf897fc312f2774588c9e`
#[derive(Debug, PartialEq, Clone)]
pub enum TorrentFile {
    /// A single file with a [usize] determining it's length in bytes (`1` in
    /// usize == 1 byte)
    Single(usize),

    /// Multiple files with a similar [usize] to [TorrentFile::Single] as the first
    /// element and a [Vec] of [String] subdirectories
    ///
    /// # BitTorrent Description
    ///
    /// ```none
    /// length - The length of the file, in bytes.
    ///
    /// path - A list of UTF-8 encoded strings corresponding to subdirectory names,
    /// the last of which is the actual file name (a zero length list is an error
    /// case).
    /// ```
    MultiFile(Vec<(usize, Vec<String>)>),
}

/// The primary representation of a torrent, created from a parsing function
/// like [bencode::parse](crate::bencode::parse). This representation is used to
/// interact with many parts of torro.
///
/// ## Documentation sourcing
///
/// All "BitTorrent Description" headings are taken from
/// [BEP0003](https://www.bittorrent.org/beps/bep_0003.html) and is subject to
/// change, like any moving standard. This documentation is based off of version
/// `0e08ddf84d8d3bf101cdf897fc312f2774588c9e`
#[derive(Debug, PartialEq, Clone)]
pub struct Torrent {
    /// URL for tracker
    ///
    /// # BitTorrent Description
    ///
    /// ```none
    /// The URL of the tracker.
    /// ```
    pub announce: String,

    /// Advised save name for torrent once leeched, is use by torro by default
    /// but may be changed
    ///
    /// # BitTorrent Description
    ///
    /// ```none
    /// The `name` key maps to a UTF-8 encoded string which is the suggested name
    /// to save the file (or directory) as. It is purely advisory.
    /// ```
    pub name: String, // TODO: allow changing once implemented

    /// File buffer (aka piece) length, commonly a power of 2 (e.g. `2`, `4`,
    /// `8`, `16`)
    ///
    /// # BitTorrent Description
    ///
    /// ```none
    /// `piece length` maps to the number of bytes in each piece the file is split
    /// into. For the purposes of transfer, files are split into fixed-size pieces
    /// which are all the same length except for possibly the last one which may
    /// be truncated. piece length is almost always a power of two, most commonly
    /// 2 18 = 256 K (BitTorrent prior to version 3.2 uses 2 20 = 1 M as default).
    /// ```
    pub piece_length: usize,

    /// A vector of binary-encoded SHA hashes corrosponding to each
    /// [Torrent::piece_length]
    ///
    /// # BitTorrent Description
    ///
    /// *Please note that torro represents this "(byte)string whose length is a
    /// multiple of 20" as a `Vec<Vec<u8>>` with each iteration of top-most vec
    /// containing a `Vec<u8>`-coded hash for simplicity*
    ///
    /// ```none
    /// `pieces` maps to a string whose length is a multiple of 20. It is to be
    /// subdivided into strings of length 20, each of which is the SHA1 hash of
    /// the piece at the corresponding index.
    /// ```
    pub pieces: Vec<Vec<u8>>,

    /// The overall file structure of the torrent, see the [TorrentFile] enum for
    /// more infomation
    ///
    /// # BitTorrent Description
    ///
    /// *We have merged the two options into a single enum for easier digesting
    /// inside of Rust*
    ///
    /// ```none
    /// There is also a key length or a key files, but not both or neither. If
    /// length is present then the download represents a single file, otherwise
    /// it represents a set of files which go in a directory structure.
    ///
    /// In the single file case, length maps to the length of the file in bytes.
    ///
    /// For the purposes of the other keys, the multi-file case is treated as
    /// only having a single file by concatenating the files in the order they
    /// appear in the files list. The files list is the value files maps to, and
    /// is a list of dictionaries containing the following keys:
    ///
    /// length - The length of the file, in bytes.
    ///
    /// path - A list of UTF-8 encoded strings corresponding to subdirectory names,
    /// the last of which is the actual file name (a zero length list is an error
    /// case).
    ///
    /// In the single file case, the name key is the name of a file, in the
    /// muliple file case, it's the name of a directory.
    /// ```
    pub file_structure: TorrentFile,
}