Skip to content

Commit 96e6178

Browse files
committed
Bug fix: Panic on empty input
1 parent 53dcddc commit 96e6178

3 files changed

Lines changed: 60 additions & 56 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/config.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use clap::{App, Arg};
2+
3+
pub struct Config {
4+
pub minimize: bool,
5+
pub separator: String,
6+
pub file: Option<String>,
7+
pub outfile: Option<String>,
8+
}
9+
10+
impl Config {
11+
pub fn from_args() -> Config {
12+
let args = App::new("mdtable")
13+
.version("1.0.1")
14+
.author("Axel Lindeberg")
15+
.about("Makes creating tables in markdown much easier!")
16+
.arg(Arg::with_name("minimize")
17+
.help("Minimizes table output")
18+
.long("minimize")
19+
.short("m")
20+
)
21+
.arg(Arg::with_name("file")
22+
.help("Reads table values from this if given, stdin otherwise.")
23+
.long("file")
24+
.short("f")
25+
.takes_value(true)
26+
)
27+
.arg(Arg::with_name("outfile")
28+
.help("Prints output to this if given, stdout otherwise.")
29+
.long("out")
30+
.short("o")
31+
.takes_value(true)
32+
)
33+
.arg(Arg::with_name("separator")
34+
.help("String that separates values.")
35+
.long("separator")
36+
.short("s")
37+
.default_value(",")
38+
)
39+
.get_matches();
40+
41+
Config {
42+
minimize: args.is_present("minimize"),
43+
separator: args.value_of("separator").map(String::from).unwrap(),
44+
file: args.value_of("file").map(String::from),
45+
outfile: args.value_of("outfile").map(String::from),
46+
}
47+
}
48+
}

src/main.rs

Lines changed: 10 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,13 @@
11
extern crate clap;
22
extern crate pad;
33

4-
use clap::{App, Arg};
5-
use pad::PadStr;
4+
mod config;
65

6+
use pad::PadStr;
77
use std::io::{self, Result, BufRead, BufReader};
88
use std::fs::{self, File};
99
use std::cmp::max;
10-
11-
type TableData = Vec<Vec<String>>;
12-
13-
struct Config {
14-
minimize: bool,
15-
separator: String,
16-
file: Option<String>,
17-
outfile: Option<String>,
18-
}
19-
20-
fn get_config() -> Config {
21-
let args = App::new("mdtable")
22-
.version("1.0.1")
23-
.author("Axel Lindeberg")
24-
.about("Makes creating tables in markdown much easier!")
25-
.arg(Arg::with_name("minimize")
26-
.help("Minimizes table output")
27-
.long("minimize")
28-
.short("m")
29-
)
30-
.arg(Arg::with_name("file")
31-
.help("Reads table values from this if given, stdin otherwise.")
32-
.long("file")
33-
.short("f")
34-
.takes_value(true)
35-
)
36-
.arg(Arg::with_name("outfile")
37-
.help("Prints output to this if given, stdout otherwise.")
38-
.long("out")
39-
.short("o")
40-
.takes_value(true)
41-
)
42-
.arg(Arg::with_name("separator")
43-
.help("String that separates values.")
44-
.long("separator")
45-
.short("s")
46-
.default_value(",")
47-
)
48-
.get_matches();
49-
50-
Config {
51-
minimize: args.is_present("minimize"),
52-
separator: args.value_of("separator").map(String::from).unwrap(),
53-
file: args.value_of("file").map(String::from),
54-
outfile: args.value_of("outfile").map(String::from),
55-
}
56-
}
10+
use config::Config;
5711

5812
fn read_lines(file: &Option<String>) -> Result<Vec<String>> {
5913
match file {
@@ -74,8 +28,8 @@ fn read_lines(file: &Option<String>) -> Result<Vec<String>> {
7428
}
7529
}
7630

77-
fn parse_table_data(lines: &Vec<String>, separator: &String) -> TableData {
78-
let mut rows: TableData = lines.iter()
31+
fn parse_table_data(lines: &Vec<String>, separator: &String) -> Vec<Vec<String>> {
32+
let mut rows: Vec<Vec<String>> = lines.iter()
7933
.map(|line| line
8034
.split(separator)
8135
.map(|word| word.trim())
@@ -86,14 +40,14 @@ fn parse_table_data(lines: &Vec<String>, separator: &String) -> TableData {
8640
let max_len = rows.iter()
8741
.map(|row| row.len())
8842
.max()
89-
.unwrap();
43+
.unwrap_or(0);
9044
for row in &mut rows {
9145
row.resize(max_len, String::new());
9246
}
9347
rows
9448
}
9549

96-
fn format_minimized(rows: &TableData) -> String {
50+
fn format_minimized(rows: &Vec<Vec<String>>) -> String {
9751
[
9852
rows[0].join("|"),
9953
vec!["---"; rows[0].len()].join("|"),
@@ -104,7 +58,7 @@ fn format_minimized(rows: &TableData) -> String {
10458
].join("\n")
10559
}
10660

107-
fn format_pretty(data: &TableData) -> String {
61+
fn format_pretty(data: &Vec<Vec<String>>) -> String {
10862
let lengths = data.iter().fold(
10963
vec![1; data[0].len()],
11064
|lens, row| row.iter()
@@ -136,12 +90,12 @@ fn format_pretty(data: &TableData) -> String {
13690
}
13791

13892
fn main() -> Result<()> {
139-
let config = get_config();
93+
let config = Config::from_args();
14094
let lines = read_lines(&config.file)?;
14195
let data = parse_table_data(&lines, &config.separator);
14296

14397
if data.len() < 2 || data[0].len() == 0 {
144-
eprintln!("Table requires at least 2 rows (including header) and 1 column.");
98+
eprintln!("Bad Input: Table requires at least 2 rows (including header) and 1 column.");
14599
std::process::exit(1);
146100
}
147101

0 commit comments

Comments
 (0)