| 62 | |
| 63 | impl App { |
| 64 | fn compute<Hasher: Digest>(&self) -> Result<()> { |
| 65 | struct BlackHole; |
| 66 | impl Write for BlackHole { |
| 67 | fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { |
| 68 | Ok(buf.len()) |
| 69 | } |
| 70 | |
| 71 | fn flush(&mut self) -> std::io::Result<()> { |
| 72 | Ok(()) |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | let mut hasher = Hasher::new(); |
| 77 | let mut buffer = vec![0u8; 1024 * 32]; |
| 78 | let input: &mut dyn Read = match &self.input { |
| 79 | Some(input_file) => { |
| 80 | if input_file == "-" { |
| 81 | &mut std::io::stdin() |
| 82 | } else { |
| 83 | let file = fs::File::open(input_file).context("Failed to open input file")?; |
| 84 | &mut { file } |
| 85 | } |
| 86 | } |
| 87 | None => &mut std::io::stdin(), |
| 88 | }; |
| 89 | let output: &mut dyn Write = match &self.output { |
| 90 | Some(output_file) => match output_file.as_str() { |
| 91 | "-" => &mut std::io::stdout(), |
| 92 | "!" => &mut BlackHole, |
| 93 | _ => { |
| 94 | let file = |
| 95 | fs::File::create(output_file).context("Failed to open output file")?; |
| 96 | &mut { file } |
| 97 | } |
| 98 | }, |
| 99 | None => &mut std::io::stdout(), |
| 100 | }; |
| 101 | let to: &mut dyn Write = match &self.to { |
| 102 | Some(to_file) => { |
| 103 | if to_file == "-" { |
| 104 | &mut std::io::stdout() |
| 105 | } else { |
| 106 | let file = fs::File::create(to_file).context("Failed to open hash file")?; |
| 107 | &mut { file } |
| 108 | } |
| 109 | } |
| 110 | None => &mut std::io::stderr(), |
| 111 | }; |
| 112 | loop { |
| 113 | let len = input |
| 114 | .read(&mut buffer) |
| 115 | .context("Failed to read from stdin")?; |
| 116 | if len == 0 { |
| 117 | break; |
| 118 | } |
| 119 | hasher.update(&buffer[..len]); |
| 120 | output |
| 121 | .write_all(&buffer[..len]) |