bstree_file_readonly/cliargs/
csvargs.rs1use csv::{Reader, ReaderBuilder};
4use std::fs::File;
5use std::io::{stdin, Error, Read};
6use std::path::PathBuf;
7use structopt::StructOpt;
8
9#[derive(Debug, StructOpt)]
10pub struct CsvArgs {
11 #[structopt(long, default_value = "8096")]
12 capacity: usize,
14 #[structopt(name = "separator", short = "s", long, default_value = ",")]
15 delimiter: char,
17 #[structopt(short = "q", long)]
18 use_double_quote: bool,
20 #[structopt(short = "e", long)]
21 use_escape: bool,
23 #[structopt(short = "x", long)]
24 flexible: bool,
26 #[structopt(short = "h", long)]
27 header: bool,
29 #[structopt(short = "c", long)]
30 comments: bool,
32 #[structopt(long, parse(from_os_str))]
33 input: Option<PathBuf>,
35}
36
37impl CsvArgs {
38 fn create_reader_builder(&self) -> ReaderBuilder {
39 let mut reader_builder = csv::ReaderBuilder::new();
40 reader_builder.delimiter(self.delimiter as u8);
41 reader_builder.has_headers(self.header);
42 reader_builder.double_quote(self.use_double_quote);
43 reader_builder.flexible(self.flexible);
44 reader_builder.buffer_capacity(self.capacity);
45 if self.use_escape {
46 reader_builder.escape(Some(b'\\'));
47 }
48 if self.comments {
49 reader_builder.comment(Some(b'#'));
50 }
51 reader_builder
52 }
53
54 pub fn call_once<F>(self, func: F) -> Result<F::Output, Error>
59 where
60 F: FnUsingReader,
61 {
62 let reader_builder = self.create_reader_builder();
64 match self.input {
66 Some(ref path_buf) => {
67 let reader = reader_builder.from_reader(File::open(path_buf)?);
68 func.call(reader)
69 }
70 None => {
71 let reader = reader_builder.from_reader(stdin());
72 func.call(reader)
73 }
74 }
75 }
76}
77
78pub trait FnUsingReader {
80 type Output;
81
82 fn call<R: Read>(self, reader: Reader<R>) -> Result<Self::Output, Error>;
83}