1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use std::fs::File;
use std::io::{self, BufRead, BufReader};
use structopt::clap::arg_enum;
arg_enum! {
#[derive(Debug, PartialEq)]
pub enum QuoteStyle {
Always,
Auto,
Never
}
}
impl QuoteStyle {
pub fn naive_surround(&self, text: &str) -> String {
match self {
Self::Always => format!("\"{}\"", text),
Self::Never => text.into(),
Self::Auto => {
if text.contains(|s: char| s.is_ascii_whitespace()) {
format!("\"{}\"", text)
} else {
text.into()
}
}
}
}
}
impl From<&str> for QuoteStyle {
fn from(string: &str) -> Self {
match string.to_lowercase().as_str() {
"always" => QuoteStyle::Always,
"never" => QuoteStyle::Never,
_ => QuoteStyle::Auto,
}
}
}
pub fn content_of(text: &str) -> Option<&str> {
let trimmed = text.trim();
if trimmed.is_empty() || trimmed.starts_with('#') {
None
} else {
for (i, _) in trimmed.match_indices('#') {
if trimmed
.chars()
.nth(i - 1)
.expect("no char before hash")
.is_ascii_whitespace()
{
return Some(trimmed[..i - 1].trim_end());
}
}
Some(trimmed)
}
}
pub fn file_reader(file: &str) -> Result<Box<dyn BufRead>, io::Error> {
match file {
"-" => Ok(Box::new(BufReader::new(io::stdin()))),
_ => Ok(Box::new(BufReader::new(File::open(&file)?))),
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_content_of() {
assert_eq!(content_of(""), None);
assert_eq!(content_of(" "), None);
assert_eq!(content_of(" yes "), Some("yes"));
assert_eq!(content_of(" yes yes "), Some("yes yes"));
assert_eq!(content_of("# test"), None);
assert_eq!(content_of(" # test"), None);
assert_eq!(content_of("yes # no"), Some("yes"));
assert_eq!(content_of("yes# yes"), Some("yes# yes"));
}
#[test]
fn test_quotes_from_str() {
assert_eq!(QuoteStyle::from("test"), QuoteStyle::Auto);
assert_eq!(QuoteStyle::from("always"), QuoteStyle::Always);
assert_eq!(QuoteStyle::from("ALWAYS"), QuoteStyle::Always);
assert_eq!(QuoteStyle::from("never"), QuoteStyle::Never);
assert_eq!(QuoteStyle::from("NEVER"), QuoteStyle::Never);
}
}