Expand description

lava_torrent is a library for parsing/encoding/creating bencode and .torrent files. It is dual-licensed under Apache 2.0 and MIT.

Quick Start

Read a torrent (v1) and print it and its info hash.

use lava_torrent::torrent::v1::Torrent;

let torrent = Torrent::read_from_file("sample.torrent").unwrap();
println!("{}", torrent);
println!("Info hash: {}", torrent.info_hash());

Create a torrent (v1) from files in a directory and save the .torrent file.

use lava_torrent::torrent::v1::TorrentBuilder;

let torrent = TorrentBuilder::new("dir/", 1048576).build().unwrap();

Bencode (de)serialization.

use lava_torrent::bencode::BencodeElem;

let bytes = "d4:spam4:eggse".as_bytes();
let dict = BencodeElem::Dictionary([("spam".to_owned(), "eggs".into())].into());

assert_eq!(BencodeElem::from_bytes(bytes).unwrap()[0], dict);
assert_eq!(dict.encode(), bytes);

assert_eq!(BencodeElem::from_file("/tmp/foo").unwrap()[0], dict);


  • It is not recommended to use lava_torrent in any critical system at this point.
  • Currently, only v1 torrents are supported. Merkle tree torrents can be supported if there’s enough demand. v2 torrents might be supported once it’s stabilized.
  • Methods for parsing and encoding are generally bound to structs (i.e. they are “associated methods”). Methods that are general enough are placed at the module-level (e.g. lava_torrent::bencode::write::encode_bytes()).


Feature Flags

  • parallel_single_file_hashing: enable parallel processing of pieces for single-file torrents


lava_torrent is written without using any existing parser or parser generator. The BitTorrent specification is also rather vague on certain points. Thus, bugs should not be a surprise. If you do find one, please open a GitHub issue.

That said, a lot of unit tests and several integration tests are written to minimize the possibility of incorrect behaviors.

Known Issues

  1. BEP 3 specifies that a bencode integer has no size limit. This is a reasonable choice as it allows the protocol to be used in the future when file sizes grow significantly. However, using a 64-bit signed integer to represent a bencode integer should be more-than sufficient even in 2018. Therefore, while technically we should use something like bigint to represent bencode integers, i64 is used in the current implementation. If a bencode integer larger than i64::max_value() is found, a LavaTorrentError will be returned.

  2. Several private methods will panic if something that “just won’t happen” happens. For the purpose of full disclosure this behavior is mentioned here, but in reality panic should never be triggered. If you want to locate these private methods try searching for “panic”, “unwrap”, and “expect” in *.rs files.

Implemented BEPs

NOTE: Only the parsing/encoding aspects are implemented.

Other Stuff

  • Feature Request: To request a feature please open a GitHub issue (please try to request only 1 feature per issue).
  • Contribution: PR is always welcome.
  • What’s with “lava”: Originally I intended to start a project for downloading/crawling stuff. When downloading files, a stream of bits will be moving around–like lava.
  • Other “lava” crates: The landscape for downloading/crawling stuff is fairly mature at this point, which means reinventing the wheels now is rather pointless… So this might be the only crate published under the “lava” name.
  • Similar crates: bip-rs


Module for bencode-related parsing/encoding.

Module for .torrent files related parsing/encoding/creation.

[Experimental] Module containing structs for tracker responses.


Custom error.