Skip to content
This repository was archived by the owner on Apr 24, 2025. It is now read-only.

Commit 41b7a7d

Browse files
committed
Support reading from stdin in join
1 parent c0d2666 commit 41b7a7d

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

src/cmd/join.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::collections::hash_map::{HashMap, Entry};
22
use std::fmt;
3-
use std::fs;
43
use std::io;
54
use std::iter::repeat;
65
use std::str;
@@ -9,7 +8,7 @@ use byteorder::{WriteBytesExt, BigEndian};
98
use csv;
109

1110
use CliResult;
12-
use config::{Config, Delimiter};
11+
use config::{Config, Delimiter, SeekRead};
1312
use index::Indexed;
1413
use select::{SelectColumns, Selection};
1514
use util;
@@ -278,7 +277,7 @@ impl<R: io::Read + io::Seek, W: io::Write> IoState<R, W> {
278277

279278
impl Args {
280279
fn new_io_state(&self)
281-
-> CliResult<IoState<fs::File, Box<io::Write+'static>>> {
280+
-> CliResult<IoState<Box<SeekRead+'static>, Box<io::Write+'static>>> {
282281
let rconf1 = Config::new(&Some(self.arg_input1.clone()))
283282
.delimiter(self.flag_delimiter)
284283
.no_headers(self.flag_no_headers)
@@ -288,8 +287,8 @@ impl Args {
288287
.no_headers(self.flag_no_headers)
289288
.select(self.arg_columns2.clone());
290289

291-
let mut rdr1 = rconf1.reader_file()?;
292-
let mut rdr2 = rconf2.reader_file()?;
290+
let mut rdr1 = rconf1.reader_file_stdin()?;
291+
let mut rdr2 = rconf2.reader_file_stdin()?;
293292
let (sel1, sel2) = self.get_selections(
294293
&rconf1, &mut rdr1, &rconf2, &mut rdr2)?;
295294
Ok(IoState {

src/config.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ pub struct Config {
7070
quoting: bool,
7171
}
7272

73+
// Empty trait as an alias for Seek and Read that avoids auto trait errors
74+
pub trait SeekRead: io::Seek + io::Read {}
75+
impl<T: io::Seek + io::Read> SeekRead for T {}
76+
7377
impl Config {
7478
pub fn new(path: &Option<String>) -> Config {
7579
let (path, delim) = match *path {
@@ -212,6 +216,21 @@ impl Config {
212216
}
213217
}
214218

219+
pub fn reader_file_stdin(&self) -> io::Result<csv::Reader<Box<SeekRead+'static>>> {
220+
Ok(match self.path {
221+
None => {
222+
// Create a buffer in memory when stdin needs to be indexed
223+
let mut buffer: Vec<u8> = Vec::new();
224+
let stdin = io::stdin();
225+
stdin.lock().read_to_end(&mut buffer)?;
226+
self.from_reader(Box::new(io::Cursor::new(buffer)))
227+
},
228+
Some(ref p) => {
229+
self.from_reader(Box::new(fs::File::open(p).unwrap()))
230+
},
231+
})
232+
}
233+
215234
pub fn index_files(&self)
216235
-> io::Result<Option<(csv::Reader<fs::File>, fs::File)>> {
217236
let (csv_file, idx_file) = match (&self.path, &self.idx_path) {

0 commit comments

Comments
 (0)