add cli tests + refactor
parent
564147daae
commit
b6e93bd5cc
@ -0,0 +1,159 @@
|
|||||||
|
|
||||||
|
use super::{Columns, Column};
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
/// split input text into columns based on separator character
|
||||||
|
/// returns a type representing a variable length array of strings (columns) ?
|
||||||
|
///
|
||||||
|
/// TODO:
|
||||||
|
///
|
||||||
|
/// error handling
|
||||||
|
/// accept &str and String
|
||||||
|
///
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InputText<'a> {
|
||||||
|
raw: &'a str,
|
||||||
|
|
||||||
|
pub sep: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> InputText<'a> {
|
||||||
|
|
||||||
|
pub fn new(raw: &'a str, sep: &str) -> Self {
|
||||||
|
InputText {
|
||||||
|
raw: raw.into(),
|
||||||
|
sep: sep.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn n_cols(&self) -> Result<usize> {
|
||||||
|
// read the first line stripping empty lines
|
||||||
|
let lines: Vec<&str> = self.raw.trim().lines().collect();
|
||||||
|
// eprintln!("lines: {:?}", lines);
|
||||||
|
|
||||||
|
let re = Regex::new(&self.sep).unwrap();
|
||||||
|
|
||||||
|
// count number of columns
|
||||||
|
match lines.first() {
|
||||||
|
Some(line) => Ok(re.split(line).count()),
|
||||||
|
None => Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(self) -> usize {
|
||||||
|
self.raw.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the number of columns given input text and a separator
|
||||||
|
pub fn n_columns(text: &str, sep: &str) -> Result<usize> {
|
||||||
|
// read the first line stripping empty lines
|
||||||
|
let lines: Vec<&str> = text.trim().lines().collect();
|
||||||
|
// eprintln!("lines: {:?}", lines);
|
||||||
|
|
||||||
|
let re = Regex::new(sep).unwrap();
|
||||||
|
|
||||||
|
// count number of columns
|
||||||
|
match lines.first() {
|
||||||
|
Some(line) => Ok(re.split(line).count()),
|
||||||
|
None => return Err(anyhow!("no lines left")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn split_columns(text: &str, sep: &str) -> Result<Columns> {
|
||||||
|
let re = Regex::new(sep).unwrap();
|
||||||
|
|
||||||
|
// eprintln!("# columns: {n_col}");
|
||||||
|
let lines: Vec<&str> = text.trim().lines().collect();
|
||||||
|
|
||||||
|
let n_col = n_columns(text, sep)?;
|
||||||
|
let mut columns = vec![Column::new(); n_col];
|
||||||
|
|
||||||
|
for (n, line) in lines.iter().enumerate() {
|
||||||
|
// eprintln!("checking line {}", i);
|
||||||
|
|
||||||
|
let new_n_col = re.split(line).count();
|
||||||
|
|
||||||
|
if new_n_col != n_col {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"unmatched column: expected {n_col} got {new_n_col} on line {}",
|
||||||
|
n + 1
|
||||||
|
));
|
||||||
|
}
|
||||||
|
// eprintln!("number of columns: {}", columns.len());
|
||||||
|
|
||||||
|
for (c_idx, col) in re.split(line).enumerate() {
|
||||||
|
columns[c_idx].push(col.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("{:?}", columns);
|
||||||
|
|
||||||
|
Ok(Columns(columns))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::DEFAULT_SEP_PATTERN;
|
||||||
|
use regex::Regex;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
type TestResult = Result<(), Box<dyn Error>>;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_split_columns_default_sep() -> TestResult {
|
||||||
|
let coltext1 = "
|
||||||
|
file1.txt\t\ttitle1
|
||||||
|
file2.pdf\t\ttitle2
|
||||||
|
file3\t\t\ttitle3
|
||||||
|
file with space \textra
|
||||||
|
";
|
||||||
|
let columns = split_columns(coltext1, DEFAULT_SEP_PATTERN)?;
|
||||||
|
|
||||||
|
// should have two columns
|
||||||
|
assert_eq!(2, columns.clone().len());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
vec!["file1.txt", "file2.pdf", "file3", "file with space "],
|
||||||
|
columns[0]
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_wrong_ncol_default_sep() {
|
||||||
|
let coltext1 = "
|
||||||
|
file1.txt\t\ttitle1
|
||||||
|
file2.pdf\t\ttitle2
|
||||||
|
file3\t\t\ttitle3
|
||||||
|
file with space\ttitle 4\textra
|
||||||
|
";
|
||||||
|
split_columns(coltext1, DEFAULT_SEP_PATTERN).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
fn test_re_split() {
|
||||||
|
let text = "this is two tabs";
|
||||||
|
let re = Regex::new(r"[\t]+").unwrap();
|
||||||
|
let fields: Vec<&str> = re.split(text).collect();
|
||||||
|
eprintln!("{:?}", fields);
|
||||||
|
assert!(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_columns_from_str() {
|
||||||
|
let res: Columns = "first column\tsecond column\t\tthird column"
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(res.len(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_input_text(){
|
||||||
|
// it =
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,8 @@
|
|||||||
.rw-r--r-- 894 root 9 Sep 22:19 coredump.conf
|
.rw-rw-r-- 11k blob42 21 Sep 23:25 Cargo.lock
|
||||||
.rw-r--r-- 540 root 20 Sep 2020 homed.conf
|
.rw-rw-r-- 303 blob42 21 Sep 23:25 Cargo.toml
|
||||||
.rw-r--r-- 766 root 9 Sep 22:19 homed.conf.pacnew
|
drwxrwxr-x - blob42 10 Sep 12:27 examples
|
||||||
.rw-r--r-- 894 root 9 Sep 22:19 journal-remote.conf
|
.rw-rw-r-- 1.6k blob42 1 Oct 17:24 README.md
|
||||||
.rw-r--r-- 822 root 9 Sep 22:19 journal-upload.conf
|
drwxrwxr-x - blob42 21 Sep 23:31 src
|
||||||
.rw-r--r-- 1.3k root 9 Sep 22:19 journald.conf
|
drwxrwxr-x - blob42 1 Oct 17:26 target
|
||||||
.rw-r--r-- 1.1k root 24 Feb 2022 logind.conf
|
drwxrwxr-x - blob42 21 Sep 00:44 tests
|
||||||
.rw-r--r-- 1.5k root 9 Sep 22:19 logind.conf.pacnew
|
.rw-rw-r-- 222 blob42 17 Sep 19:03 TODO.md
|
||||||
drwxr-xr-x - root 25 Jan 18:33 network
|
|
||||||
.rw-r--r-- 872 root 9 Sep 22:19 networkd.conf
|
|
||||||
.rw-r--r-- 804 root 9 Sep 22:19 oomd.conf
|
|
||||||
.rw-r--r-- 670 root 9 Sep 22:19 pstore.conf
|
|
||||||
.rw-r--r-- 763 root 19 Aug 2020 resolved.conf
|
|
||||||
.rw-r--r-- 1.6k root 9 Sep 22:19 resolved.conf.pacnew
|
|
||||||
.rw-r--r-- 953 root 9 Sep 22:19 sleep.conf
|
|
||||||
drwxr-xr-x - root 2 Feb 18:04 system
|
|
||||||
.rw-r--r-- 2.2k root 9 Sep 22:19 system.conf
|
|
||||||
.rw-r--r-- 856 root 9 Sep 22:19 timesyncd.conf
|
|
||||||
drwxr-xr-x - root 9 Nov 2022 user
|
|
||||||
.rw-r--r-- 1.6k root 9 Sep 22:19 user.conf
|
|
||||||
|
Loading…
Reference in New Issue