diff --git a/src/lib.rs b/src/lib.rs index aa71baf..88a5841 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,7 +54,7 @@ const MANIFEST_TOPIC_RE_STR: &str = r"mt=((\w+)[A-Za-z0-9!@#$%^:*<>,?/()_+=.{}\\ /// ``` /// use magnet_url::Magnet; /// let magneturl = Magnet::new("magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent").unwrap(); -/// println!("{:?}", magneturl.dn); +/// println!("{:?}", magneturl.display_name); /// ``` /// /// If you'd like to modify parts of the magnet_url to customize it, that can be done as well! @@ -62,9 +62,9 @@ const MANIFEST_TOPIC_RE_STR: &str = r"mt=((\w+)[A-Za-z0-9!@#$%^:*<>,?/()_+=.{}\\ /// ``` /// use magnet_url::Magnet; /// let mut magneturl = Magnet::new("magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent").unwrap(); -/// println!("{:?}", magneturl.dn); -/// magneturl.dn = Some(String::from("hello_world")); -/// println!("{:?}", magneturl.dn); +/// println!("{:?}", magneturl.display_name); +/// magneturl.display_name = Some(String::from("hello_world")); +/// println!("{:?}", magneturl.display_name); /// ``` /// /// In fact, you can construct your own magnet url as well, as long as you fill in all the @@ -74,16 +74,16 @@ const MANIFEST_TOPIC_RE_STR: &str = r"mt=((\w+)[A-Za-z0-9!@#$%^:*<>,?/()_+=.{}\\ /// use magnet_url::Magnet; /// //Note, this magnet won't actually download, sorry :/ /// Magnet { -/// dn: Some("hello_world".to_string()), +/// display_name: Some("hello_world".to_string()), /// hash_type: Some("sha1".to_string()), -/// xt: Some("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed".to_string()), -/// xl: Some(1234567890), -/// tr: vec!["https://example.com/".to_string()], -/// kt: Some("cool+stuff".to_string()), -/// ws: None, +/// hash: Some("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed".to_string()), +/// length: Some(1234567890), +/// trackers: vec!["https://example.com/".to_string()], +/// search_keywords: Some("cool+stuff".to_string()), +/// web_seed: None, /// acceptable_source: None, -/// mt: None, -/// xs: None, +/// manifest: None, +/// source: None, /// }; /// ``` /// @@ -93,16 +93,16 @@ const MANIFEST_TOPIC_RE_STR: &str = r"mt=((\w+)[A-Za-z0-9!@#$%^:*<>,?/()_+=.{}\\ /// use magnet_url::Magnet; /// //Note, this magnet won't actually download, sorry :/ /// let magnet_struct = Magnet { -/// dn: Some("hello_world".to_string()), +/// display_name: Some("hello_world".to_string()), /// hash_type: Some("sha1".to_string()), -/// xt: Some("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed".to_string()), -/// xl: Some(1234567890), -/// tr: vec!["https://example.com/".to_string()], -/// kt: Some("cool+stuff".to_string()), -/// ws: None, +/// hash: Some("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed".to_string()), +/// length: Some(1234567890), +/// trackers: vec!["https://example.com/".to_string()], +/// search_keywords: Some("cool+stuff".to_string()), +/// web_seed: None, /// acceptable_source: None, -/// mt: None, -/// xs: None, +/// manifest: None, +/// source: None, /// }; /// /// let magnet_string = magnet_struct.to_string(); @@ -123,36 +123,34 @@ pub enum MagnetError { #[derive(Debug, Clone, Hash, PartialEq)] pub struct Magnet { - ///Display Name of the torrent - pub dn: Option, - ///type of hash used in the exact topic + /// Display Name of the torrent + pub display_name: Option, + /// Type of hash used in the exact topic pub hash_type: Option, - ///eXact Topic: URN containing the file hash. The URN is specific to the protocol so a file hash - /// URN under btih (BitTorrent) would be completely different than the file hash URN for ed2k - pub xt: Option, - ///eXact Length: The size (in bytes) - pub xl: Option, - ///eXact Source: Either an HTTP (or HTTPS, FTP, FTPS, etc.) download source for the file pointed + /// (xt / exact topic) Torrent hash. + pub hash: Option, + /// (xl): The size (in bytes) of the torrent. + pub length: Option, + /// (ex): Either an HTTP (or HTTPS, FTP, FTPS, etc.) download source for the file pointed /// to by the Magnet link, the address of a P2P source for the file or the address of a hub (in /// the case of DC++), by which a client tries to connect directly, asking for the file and/or /// its sources. This field is commonly used by P2P clients to store the source, and may include /// the file hash. - pub xs: Option, - ///address TRacker: Tracker URL; used to obtain resources for BitTorrent downloads without a + pub source: Option, + /// Tracker URLs (tr) used to obtain resources for BitTorrent downloads without a /// need for DHT support. The value must be URL encoded - pub tr: Vec, - ///Keyword Topic: Specifies a string of search keywords to search for in P2P networks, rather + pub trackers: Vec, + /// (kt) A string of search keywords to search for in P2P networks, rather /// than a particular file. Also set as a vector since there will likely be more than one - pub kt: Option, - ///Web Seed: The payload data served over HTTP(S) - pub ws: Option, - ///Acceptable Source: Refers to a direct download from a web server. Regarded as only a + pub search_keywords: Option, + /// (ws) The payload data served over HTTP(S) + pub web_seed: Option, + /// (as) Refers to a direct download from a web server. Regarded as only a /// fall-back source in case a client is unable to locate and/or download the linked-to file in its supported P2P network(s) - ///as is a reserved keyword in Rust, so unfortunately this library must use the full name + /// as is a reserved keyword in Rust, so unfortunately this library must use the full name pub acceptable_source: Option, - ///Manifest Topic: Link to the metafile that contains a list of magneto (MAGMA – - /// MAGnet MAnifest); i.e. a link to a list of links - pub mt: Option, + /// (mt) Link to the metafile that contains a list of magneto (MAGMA – MAGnet MAnifest); i.e. a link to a list of links + pub manifest: Option, } impl Magnet { @@ -185,19 +183,19 @@ impl Magnet { }; Magnet { - dn: validate_regex(&DISPLAY_NAME_RE, 1), + display_name: validate_regex(&DISPLAY_NAME_RE, 1), hash_type: validate_regex(&EXACT_TOPIC_RE, 1), - xt: validate_regex(&EXACT_TOPIC_RE, 2), + hash: validate_regex(&EXACT_TOPIC_RE, 2), // Using a slightly modified match statement so it doesn't parse from str to String to int - xl: { + length: { match &EXACT_LENGTH_RE.captures(magnet_str) { Some(m) => m.get(1).map_or(None, |m| Some(m.as_str().parse().unwrap())), None => None, } }, - xs: validate_regex(&EXACT_SOURCE_RE, 1), - tr: { + source: validate_regex(&EXACT_SOURCE_RE, 1), + trackers: { let mut tr_vec: Vec = Vec::new(); // Since tr is a vector, I can't just use the validate_regex function for tr in ADDRESS_TRACKER_RE.captures_iter(magnet_str) { @@ -207,10 +205,10 @@ impl Magnet { tr_vec }, - kt: validate_regex(&KEYWORD_TOPIC_RE, 1), - ws: validate_regex(&WEB_SEED_RE, 1), + search_keywords: validate_regex(&KEYWORD_TOPIC_RE, 1), + web_seed: validate_regex(&WEB_SEED_RE, 1), acceptable_source: validate_regex(&ACCEPTABLE_SOURCE_RE, 1), - mt: validate_regex(&MANIFEST_TOPIC_RE, 1), + manifest: validate_regex(&MANIFEST_TOPIC_RE, 1), } } @@ -236,7 +234,7 @@ impl fmt::Display for Magnet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut magnet_string = String::from("magnet:?"); - if let Some(xt) = &self.xt { + if let Some(xt) = &self.hash { magnet_string = format!("{}{}{}:{}", magnet_string, "xt=urn:", self.hash_type.as_ref().unwrap_or(&String::new()), xt); } @@ -250,26 +248,26 @@ impl fmt::Display for Magnet { } }; - magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("dn"), &self.dn)); + magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("dn"), &self.display_name)); - if let Some(xl) = &self.xl { + if let Some(xl) = &self.length { magnet_string = format!("{}&xl={}", magnet_string, xl); } magnet_string = { let mut tr_string = String::new(); - for tracker in &self.tr { + for tracker in &self.trackers { tr_string = format!("{}&tr={}", tr_string, tracker); } format!("{}{}", magnet_string, tr_string) }; - magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("ws"), &self.ws)); - magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("xs"), &self.xs)); - magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("kt"), &self.kt)); + magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("ws"), &self.web_seed)); + magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("xs"), &self.source)); + magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("kt"), &self.search_keywords)); magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("as"), &self.acceptable_source)); - magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("mt"), &self.mt)); + magnet_string = format!("{}{}", magnet_string, add_to_mag_string(String::from("mt"), &self.manifest)); write!(f, "{}", magnet_string) @@ -286,24 +284,24 @@ mod tests { const MAGNET_STR: &str = "magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent"; let magnet_link = Magnet::new(MAGNET_STR).unwrap(); - assert_eq!(magnet_link.dn, Some("Sintel".to_string())); + assert_eq!(magnet_link.display_name, Some("Sintel".to_string())); assert_eq!(magnet_link.hash_type, Some("btih".to_string())); - assert_eq!(magnet_link.xt, Some("08ada5a7a6183aae1e09d831df6748d566095a10".to_string())); - assert_eq!(magnet_link.xl, None); - assert_eq!(magnet_link.xs, Some("https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent".to_string())); - assert_eq!(magnet_link.tr[0], "udp%3A%2F%2Fexplodie.org%3A6969".to_string()); - assert_eq!(magnet_link.tr[1], "udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969".to_string()); - assert_eq!(magnet_link.tr[2], "udp%3A%2F%2Ftracker.empire-js.us%3A1337".to_string()); - assert_eq!(magnet_link.tr[3], "udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969".to_string()); - assert_eq!(magnet_link.tr[4], "udp%3A%2F%2Ftracker.opentrackr.org%3A1337".to_string()); - assert_eq!(magnet_link.tr[5], "wss%3A%2F%2Ftracker.btorrent.xyz".to_string()); - assert_eq!(magnet_link.tr[6], "wss%3A%2F%2Ftracker.fastcast.nz".to_string()); - assert_eq!(magnet_link.tr[7], "wss%3A%2F%2Ftracker.openwebtorrent.com".to_string()); - assert_eq!(magnet_link.ws, Some("https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F".to_string())); - assert_eq!(magnet_link.xs, Some("https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent".to_string())); - assert_eq!(magnet_link.kt, None); + assert_eq!(magnet_link.hash, Some("08ada5a7a6183aae1e09d831df6748d566095a10".to_string())); + assert_eq!(magnet_link.length, None); + assert_eq!(magnet_link.source, Some("https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent".to_string())); + assert_eq!(magnet_link.trackers[0], "udp%3A%2F%2Fexplodie.org%3A6969".to_string()); + assert_eq!(magnet_link.trackers[1], "udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969".to_string()); + assert_eq!(magnet_link.trackers[2], "udp%3A%2F%2Ftracker.empire-js.us%3A1337".to_string()); + assert_eq!(magnet_link.trackers[3], "udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969".to_string()); + assert_eq!(magnet_link.trackers[4], "udp%3A%2F%2Ftracker.opentrackr.org%3A1337".to_string()); + assert_eq!(magnet_link.trackers[5], "wss%3A%2F%2Ftracker.btorrent.xyz".to_string()); + assert_eq!(magnet_link.trackers[6], "wss%3A%2F%2Ftracker.fastcast.nz".to_string()); + assert_eq!(magnet_link.trackers[7], "wss%3A%2F%2Ftracker.openwebtorrent.com".to_string()); + assert_eq!(magnet_link.web_seed, Some("https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F".to_string())); + assert_eq!(magnet_link.source, Some("https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent".to_string())); + assert_eq!(magnet_link.search_keywords, None); assert_eq!(magnet_link.acceptable_source, None); - assert_eq!(magnet_link.mt, None); + assert_eq!(magnet_link.manifest, None); //Need to recreate a magnet struct from the string, since the elements could be in any order assert_eq!(Magnet::new(&magnet_link.to_string()).unwrap(), magnet_link);