diff --git a/CHANGELOG.md b/CHANGELOG.md index 81840b5..d1de5a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,10 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 other variants, and other rust types - `TrackerScheme` no longer derives de/serialize because that's not actually used in torrent files -- A torrent file with an invalid tracker URI (such as an unknown scheme) will now - fail to parse as a `DecodedTorrent` and therefore as a `TorrentFile`, unless the - `unknown_tracker_scheme` variant is enabled, in which case it will produce a - valid `TorrentFile` where the `TrackerScheme` is of the `Unknown` variant +- A torrent file with an invalid tracker URI (eg. non-urlencoded or unknown + scheme) will now fail to parse as a `DecodedTorrent` and therefore as a + `TorrentFile`; if the `unknown_tracker_scheme` variant is enabled, the + unknown scheme will not produce an error but a `TrackerScheme::Unknown` ### Added diff --git a/src/magnet.rs b/src/magnet.rs index bfa4b62..82f6438 100644 --- a/src/magnet.rs +++ b/src/magnet.rs @@ -116,9 +116,6 @@ impl std::error::Error for MagnetLinkError { /// A Magnet URI, which contains the infohash(es) but not the entire meta info. /// -/// The MagnetLink can provide information about the torrent -/// [`name`](crate::magnet::MagnetLink::name) and [`hash`](crate::magnet::MagnetLink::hash). -/// /// More information is specified in [BEP-0009](https://bittorrent.org/beps/bep_0009.html), and /// even more appears in the wild, as explained [on Wikipedia](https://en.wikipedia.org/wiki/Magnet_URI_scheme). #[derive(Clone, Debug)] @@ -133,6 +130,9 @@ pub struct MagnetLink { /// `magnet_force_name` crate feature is enabled. name: String, /// Trackers contained in the magnet link + /// + /// The trackers are url-encoded in the magnet link, but are presented here + /// in their decoded form which can is human-readable. trackers: Vec, } @@ -266,7 +266,7 @@ impl MagnetLink { /// Parse the query in a list of key->value entries with a percent-decoder attached. /// - /// The results can be accessed raw with [EStr::as_str()] and percent-decoded with [EStr::decode]. + /// The results can be accessed raw with [EStr::as_str] and percent-decoded with [EStr::decode]. /// /// This method only fails if the magnet query is empty (`magnet:`), but may produce unexpected /// results because it does not apply magnet-specific sanitation. diff --git a/src/torrent_file.rs b/src/torrent_file.rs index b3d0b93..aca58a8 100644 --- a/src/torrent_file.rs +++ b/src/torrent_file.rs @@ -79,6 +79,12 @@ impl std::error::Error for TorrentFileError { /// [`name`](crate::torrent_file::TorrentFile::name) and /// [`hash`](crate::torrent_file::TorrentFile::hash). Other fields could be supported, but are not /// currently implemented by this library. +/// +/// To save the torrent file to disk, use the `TorrentFile::to_vec` method: +/// +/// ```ignore +/// std::fs::write("export.torrent", &torrent.to_vec()).unwrap(); +/// ``` #[derive(Clone, Debug, Serialize, Deserialize)] pub struct TorrentFile { pub hash: InfoHash, diff --git a/src/tracker.rs b/src/tracker.rs index 6896c0a..b1548b5 100644 --- a/src/tracker.rs +++ b/src/tracker.rs @@ -12,15 +12,25 @@ pub enum PeerSource { Tracker(Tracker), } -/// A centralized variant of a [`Peersource`](crate::tracker::PeerSource). +/// A Bittorrent rendezvous server for peers to find one another. +/// +/// This is usually parsed directly from a [`TorrentFile`](crate::torrent_file::TorrentFile) +/// or a [`MagnetLink`](crate::magnet::MagnetLink). #[derive(Clone, Debug, PartialEq)] pub struct Tracker { + /// Tracker URL scheme (usually `ws`, `http(s)`, or `udp`) scheme: TrackerScheme, + /// Complete tracker URL url: Uri, } impl Tracker { /// Generate a new Tracker from a given string URL. + /// + /// Will fail if scheme is not "http", "https", "wss" or "udp", unless + /// the `unknown_tracker_scheme` crate feature is enabled. + /// + /// Will also fail if the provided URL is url-encoded. pub fn new(url: &str) -> Result { let url = Uri::parse(url.to_string())?; Tracker::from_url(&url) @@ -28,7 +38,8 @@ impl Tracker { /// Generate a new Tracker from a parsed URL. /// - /// Will fail if scheme is not "http", "https", "wss" or "udp". + /// Will fail if scheme is not "http", "https", "wss" or "udp", unless + /// the `unknown_tracker_scheme` crate feature is enabled. pub fn from_url(url: &Uri) -> Result { Ok(Tracker { scheme: TrackerScheme::from_str(url.scheme().as_str())?, @@ -120,7 +131,14 @@ impl FromStr for TrackerScheme { /// Error occurred during parsing a [`Tracker`](crate::tracker::Tracker). #[derive(Clone, Debug, PartialEq)] pub enum TrackerError { + /// Tracker URL could not be parsed because it is malformed. + /// + /// I'm not sure under what circumstances this could happen. InvalidURL { source: UriParseError }, + /// Tracker scheme is not a known variant. + /// + /// This error does not exist when the `unknown_tracker_scheme` crate + /// feature is enabled. InvalidScheme { scheme: String }, }