Skip to content

Commit

Permalink
Write torrent to stdout if - is passed to --output
Browse files Browse the repository at this point in the history
type: added
  • Loading branch information
casey committed Apr 8, 2020
1 parent 5a1de1a commit df33265
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 27 deletions.
4 changes: 4 additions & 0 deletions src/capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ impl Capture {
.unwrap()
.to_owned()
}

pub(crate) fn bytes(&self) -> Vec<u8> {
self.cursor.borrow().get_ref().clone()
}
}

impl Write for Capture {
Expand Down
2 changes: 1 addition & 1 deletion src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub(crate) use crate::{
bytes::Bytes, env::Env, error::Error, file_info::FileInfo, files::Files, hasher::Hasher,
info::Info, lint::Lint, linter::Linter, metainfo::Metainfo, mode::Mode, opt::Opt,
piece_length_picker::PieceLengthPicker, platform::Platform, style::Style, table::Table,
torrent_summary::TorrentSummary, use_color::UseColor,
target::Target, torrent_summary::TorrentSummary, use_color::UseColor,
};

// test stdlib types
Expand Down
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
clippy::result_expect_used,
clippy::result_unwrap_used,
clippy::shadow_reuse,
clippy::too_many_lines,
clippy::unreachable,
clippy::unseparated_literal_suffix,
clippy::wildcard_enum_match_arm
Expand Down Expand Up @@ -76,6 +77,7 @@ mod platform_interface;
mod reckoner;
mod style;
mod table;
mod target;
mod torrent_summary;
mod use_color;

Expand Down
26 changes: 13 additions & 13 deletions src/opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,6 @@ use crate::common::*;

mod torrent;

#[derive(StructOpt)]
pub(crate) enum Subcommand {
Torrent(torrent::Torrent),
}

impl Subcommand {
pub(crate) fn run(self, env: &mut Env, unstable: bool) -> Result<(), Error> {
match self {
Self::Torrent(torrent) => torrent.run(env, unstable),
}
}
}

#[derive(StructOpt)]
#[structopt(
about(consts::ABOUT),
Expand Down Expand Up @@ -51,3 +38,16 @@ impl Opt {
self.subcommand.run(env, self.unstable)
}
}

#[derive(StructOpt)]
pub(crate) enum Subcommand {
Torrent(torrent::Torrent),
}

impl Subcommand {
pub(crate) fn run(self, env: &mut Env, unstable: bool) -> Result<(), Error> {
match self {
Self::Torrent(torrent) => torrent.run(env, unstable),
}
}
}
44 changes: 33 additions & 11 deletions src/opt/torrent/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ Note: Many BitTorrent clients do not implement the behavior described in BEP 12.
name = "INPUT",
long = "input",
help = "Read torrent contents from `INPUT`.",
long_help = "Read torrent contents from `INPUT`. If `INPUT` is a file, torrent will be a single-file torrent, otherwise if `INPUT` is a directory, torrent will be a multi-file torrent."
long_help = "Read torrent contents from `INPUT`. If `INPUT` is a file, torrent will be a single-file torrent, otherwise if `INPUT` is a directory, torrent will be a multi-file torrent.",
parse(from_os_str)
)]
input: PathBuf,
#[structopt(
Expand Down Expand Up @@ -85,9 +86,10 @@ Note: Many BitTorrent clients do not implement the behavior described in BEP 12.
#[structopt(
name = "OUTPUT",
long = "output",
help = "Save `.torrent` file to `OUTPUT`. Defaults to `$INPUT.torrent`."
help = "Save `.torrent` file to `OUTPUT`, or `-` for standard output. Defaults to `$INPUT.torrent`.",
parse(from_os_str)
)]
output: Option<PathBuf>,
output: Option<Target>,
#[structopt(
name = "PIECE-LENGTH",
long = "piece-length",
Expand Down Expand Up @@ -175,12 +177,12 @@ impl Create {
let output = self
.output
.as_ref()
.map(|output| env.resolve(&output))
.map(|output| output.resolve(env))
.unwrap_or_else(|| {
let mut torrent_name = name.to_owned();
torrent_name.push_str(".torrent");

input.parent().unwrap().join(torrent_name)
Target::File(input.parent().unwrap().join(torrent_name))
});

let private = if self.private { Some(1) } else { None };
Expand Down Expand Up @@ -228,12 +230,15 @@ impl Create {

let bytes = metainfo.serialize()?;

fs::write(&output, &bytes).context(error::Filesystem { path: &output })?;

TorrentSummary::from_metainfo(metainfo)?.write(env)?;

if self.open {
Platform::open(&output)?;
match &output {
Target::File(path) => {
fs::write(path, &bytes).context(error::Filesystem { path })?;
TorrentSummary::from_metainfo(metainfo)?.write(env)?;
if self.open {
Platform::open(&path)?;
}
}
Target::Stdio => env.out.write_all(&bytes).context(error::Stdout)?,
}

Ok(())
Expand Down Expand Up @@ -890,4 +895,21 @@ Content Size 0 bytes
";
assert_eq!(have, want);
}

#[test]
fn write_to_stdout() {
let mut env = environment(&[
"--input",
"foo",
"--announce",
"http://bar",
"--output",
"-",
]);
fs::write(env.resolve("foo"), "").unwrap();
env.run().unwrap();
let bytes = env.out_bytes();
let value = bencode::Value::decode(&bytes).unwrap();
assert!(matches!(value, bencode::Value::Dict(_)));
}
}
3 changes: 2 additions & 1 deletion src/opt/torrent/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ pub(crate) struct Show {
#[structopt(
name = "TORRENT",
long = "input",
help = "Show information about `TORRENT`."
help = "Show information about `TORRENT`.",
parse(from_os_str)
)]
input: PathBuf,
}
Expand Down
3 changes: 2 additions & 1 deletion src/opt/torrent/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ Extract and display values under key paths that match `REGEX`. Subkeys of a benc
long = "input",
short = "i",
help = "Search `INPUT` for torrents.",
long_help = "Search `INPUT` for torrents. May be a directory to search or a single torrent file."
long_help = "Search `INPUT` for torrents. May be a directory to search or a single torrent file.",
parse(from_os_str)
)]
input: PathBuf,
#[structopt(
Expand Down
41 changes: 41 additions & 0 deletions src/target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::common::*;

#[derive(PartialEq, Debug)]
pub(crate) enum Target {
File(PathBuf),
Stdio,
}

impl Target {
pub(crate) fn resolve(&self, env: &Env) -> Self {
match self {
Self::File(path) => Self::File(env.resolve(path)),
Self::Stdio => Self::Stdio,
}
}
}

impl From<&OsStr> for Target {
fn from(text: &OsStr) -> Self {
if text == OsStr::new("-") {
Self::Stdio
} else {
Self::File(text.into())
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn file() {
assert_eq!(Target::from(OsStr::new("foo")), Target::File("foo".into()));
}

#[test]
fn stdio() {
assert_eq!(Target::from(OsStr::new("-")), Target::Stdio);
}
}
4 changes: 4 additions & 0 deletions src/test_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ impl TestEnv {
pub(crate) fn out(&self) -> String {
self.out.string()
}

pub(crate) fn out_bytes(&self) -> Vec<u8> {
self.out.bytes()
}
}

impl Deref for TestEnv {
Expand Down

0 comments on commit df33265

Please sign in to comment.