feat: initial commit

This commit is contained in:
Chen Asraf
2023-05-04 01:17:34 +03:00
commit 6134c651c8
3 changed files with 111 additions and 0 deletions

14
.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

15
Cargo.toml Normal file
View File

@@ -0,0 +1,15 @@
[package]
name = "tbl"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
strip = true # Automatically strip symbols from the binary.
opt-level = "z" # Optimize for size.
lto = true # link time optimization
codegen-units = 1 # reduce binary size
panic = "abort" # abort on panic
[dependencies]

82
src/main.rs Normal file
View File

@@ -0,0 +1,82 @@
use std::env;
fn main() {
// get args
let args: Vec<String> = env::args().collect();
let args = &args[1..];
if args.len() < 2 {
// try get from stdin
let mut input_str = String::new();
let mut collect_str = String::new();
while std::io::stdin().read_line(&mut input_str).unwrap() > 0 {
collect_str.push_str(&input_str);
input_str.clear();
}
if collect_str.len() == 0 {
println!("Usage: {} <separator>", args[0]);
return;
}
let separator = &args[0];
let out = format_as_table(&collect_str, separator);
println!("{}", out);
return;
}
let separator = &args[1];
let input_str = &args[0];
let out = format_as_table(&input_str, separator);
println!("{}", out);
}
fn format_as_table(input_str: &str, separator: &str) -> String {
let mut result = String::new();
let mut max_col_len = Vec::new();
let mut rows = Vec::new();
for line in input_str.lines() {
let row = split_line(&line, &separator);
rows.push(row);
}
for row in &rows {
for (i, col) in row.iter().enumerate() {
if i >= max_col_len.len() {
max_col_len.push(col.len());
} else if col.len() > max_col_len[i] {
max_col_len[i] = col.len();
}
}
}
for row in &rows {
for (i, col) in row.iter().enumerate() {
result.push_str(col);
if i < row.len() - 1 {
let spaces = max_col_len[i] - col.len();
for _ in 0..spaces {
result.push(' ');
}
result.push_str(separator);
}
}
result.push('\n');
}
result
}
fn split_line<'a>(line: &'a str, separator: &'a str) -> Vec<&'a str> {
let mut result = Vec::new();
let mut start = 0;
let mut end = 0;
while end < line.len() {
if line[end..].starts_with(separator) {
if start != end {
result.push(&line[start..end]);
}
start = end + separator.len();
end = start;
} else {
end += 1;
}
}
if start != end {
result.push(&line[start..end]);
}
result
}