diff --git a/src/main.rs b/src/main.rs index d130bc7..96a7938 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ fn main() { if let Some(path) = cli.path.as_deref() { let path_string = path.display().to_string(); - let mut output_csv_item: String = String::new(); + let mut todos: Vec<(String, String, String, String, u8)> = Vec::new(); match read_files_in_directory(&path_string.as_str()) { Ok(files_content) => { @@ -54,18 +54,15 @@ fn main() { if let Some(todo_comment) = extract_todo_comment(line) { let (adjusted_todo_comment, uscore) = extract_uscore(&todo_comment); let line_number_str = (line_number + 1).to_string(); // Convert line number to String - let uscore_str = uscore.to_string(); // Convert uscore to String - if !output_csv_item.is_empty() { - output_csv_item.push_str(","); - } - - output_csv_item.push_str(&format!("{},{},{},{},{}", path_string, filename, line_number_str, adjusted_todo_comment, uscore_str)); + todos.push((path_string.clone(), filename.clone(), line_number_str, adjusted_todo_comment, uscore)); } } - } } + + // Sort todos by uscore (descending order) + todos.sort_by(|(_, _, _, _, uscore1), (_, _, _, _, uscore2)| uscore2.cmp(uscore1)); } Err(err) => { eprintln!("Error: {}", err); @@ -74,10 +71,10 @@ fn main() { if let Some(format) = cli.format.as_deref() { match format { - "md" | "MD" => out_as_md_table(output_csv_item.clone()), - "json" | "JSON" => out_as_json_object(output_csv_item.clone()), - "yaml" | "YAML" => out_as_yaml_file(output_csv_item.clone()), - "toml" | "TOML" => out_as_toml_file(output_csv_item.clone()), + "md" | "MD" => out_as_md_table(todos), + "json" | "JSON" => out_as_json_object(todos), + "yaml" | "YAML" => out_as_yaml_file(todos), + "toml" | "TOML" => out_as_toml_file(todos), _ => println!("That's not a supported format") } } @@ -114,6 +111,7 @@ fn extract_todo_comment(line: &str) -> Option { } None } + fn extract_uscore(comment: &str) -> (String, u8) { // Initialize uscore to 0 by default let mut uscore = 0; @@ -139,94 +137,59 @@ fn extract_uscore(comment: &str) -> (String, u8) { (comment.to_string(), uscore) } -fn out_as_md_table(input_csv: String) { - let mut split_input: Vec<&str> = input_csv.split(',').collect(); +fn out_as_md_table(todos: Vec<(String, String, String, String, u8)>) { let headers = String::from("| File Path | File Name | Line Number | Comment | Uscore |"); let divider = String::from("|:----------|:---------:|:-----------:|:--------|:------|"); let mut table: Vec = Vec::new(); table.push(headers); table.push(divider); - split_and_print(&mut split_input, &mut table); + + for (path, filename, line_number, comment, uscore) in todos { + let formatted_row = format!("| {} | {} | {} | {} | {} |", path, filename, line_number, comment, uscore); + table.push(formatted_row); + } for line in table { println!("{}", line); } } -fn split_and_print(vec: &mut Vec<&str>, table: &mut Vec) { - while !vec.is_empty() { - // Extract elements from the vec - let path = vec.remove(0).trim().to_string(); - let name = vec.remove(0).trim().to_string(); - let line = vec.remove(0).trim().to_string(); - let comment = vec.remove(0).trim().to_string(); - - // Uscore is the last element and needs parsing - let uscore = if let Some(last) = vec.pop() { - last.trim().parse::().unwrap_or(0) - } else { - 0 - }; - - // Format as Markdown table row - let formatted_row = format!("| {} | {} | {} | {} | {} |", path, name, line, comment, uscore); - table.push(formatted_row); - } -} - -fn out_as_json_object(input_csv: String) { +fn out_as_json_object(todos: Vec<(String, String, String, String, u8)>) { let mut output: Vec = Vec::new(); let object_open_char = "{".to_string(); let object_close_char = "}".to_string(); - let mut split_input: Vec<&str> = input_csv.split(',').collect(); - let rows: Vec = split_csv(&mut split_input, 5); - output.push(object_open_char.clone()); - for row in rows { - let mut cols: Vec<_> = row.split(',').collect(); - let obj_open = " {"; - let obj_close = " },"; - let uscore = format!(" \"uscore\":\"{}\",", cols.pop().unwrap()); - let comment = format!(" \"todo_comment\":\"{}\",", cols.pop().unwrap()); - let line_number = format!(" \"line_number\":\"{}\",", cols.pop().unwrap()); - let file_name = format!(" \"file_name\":\"{}\",", cols.pop().unwrap()); - let file_path = format!(" \"file_path\":\"{}\",", cols.pop().unwrap()); - output.push(obj_open.to_string()); - output.push(file_path.clone()); - output.push(file_name.clone()); - output.push(line_number.clone()); - output.push(comment.clone()); - output.push(uscore.clone()); - output.push(obj_close.to_string()); + for (path, filename, line_number, comment, uscore) in todos { + let mut obj_content = String::new(); + obj_content.push_str(" {"); + obj_content.push_str(&format!("\"file_path\": \"{}\", ", path)); + obj_content.push_str(&format!("\"file_name\": \"{}\", ", filename)); + obj_content.push_str(&format!("\"line_number\": \"{}\", ", line_number)); + obj_content.push_str(&format!("\"todo_comment\": \"{}\", ", comment)); + obj_content.push_str(&format!("\"uscore\": \"{}\"", uscore)); + obj_content.push_str("},"); + output.push(obj_content); } + output.push(object_close_char); for line in output { println!("{}", line) } } -fn out_as_toml_file(input_csv: String) { - let mut split_input: Vec<&str> = input_csv.split(',').collect(); - split_input.retain(|&x| x.trim() != ""); +fn out_as_toml_file(todos: Vec<(String, String, String, String, u8)>) { + let mut todos_map: HashMap> = HashMap::new(); - let mut todos: HashMap> = HashMap::new(); - - while !split_input.is_empty() { - let path = split_input.remove(0).trim().to_string(); - let file = split_input.remove(0).trim().to_string(); - let line = split_input.remove(0).trim().to_string(); - let comment = split_input.remove(0).trim().to_string(); - let uscore = split_input.remove(0).trim().parse::().unwrap_or(0); - let header = format!("{}{}", path, file); - - todos.entry(header.clone()).or_insert(Vec::new()).push((line.clone(), comment.clone(), uscore)); + for (path, filename, line_number, comment, uscore) in todos { + let header = format!("{}{}", path, filename); + todos_map.entry(header.clone()).or_insert(Vec::new()).push((line_number.clone(), comment.clone(), uscore)); } let mut toml_output = String::new(); - for (header, todo_list) in todos { + for (header, todo_list) in todos_map { toml_output.push_str(&format!("[{}]\n", header)); for (i, (line, comment, uscore)) in todo_list.iter().enumerate() { @@ -243,25 +206,16 @@ fn out_as_toml_file(input_csv: String) { println!("{}", toml_output); } -fn out_as_yaml_file(input_csv: String) { - let mut split_input: Vec<&str> = input_csv.split(',').collect(); - split_input.retain(|&x| x.trim() != ""); +fn out_as_yaml_file(todos: Vec<(String, String, String, String, u8)>) { + let mut todos_map: HashMap> = HashMap::new(); - let mut todos: HashMap> = HashMap::new(); - - while !split_input.is_empty() { - let path = split_input.remove(0).trim().to_string(); - let file = split_input.remove(0).trim().to_string(); - let line = split_input.remove(0).trim().to_string(); - let comment = split_input.remove(0).trim().to_string(); - let uscore = split_input.remove(0).trim().parse::().unwrap_or(0); - let header = format!("{}{}", path, file); - - todos.entry(header.clone()).or_insert(Vec::new()).push((line.clone(), comment.clone(), uscore)); + for (path, filename, line_number, comment, uscore) in todos { + let header = format!("{}{}", path, filename); + todos_map.entry(header.clone()).or_insert(Vec::new()).push((line_number.clone(), comment.clone(), uscore)); } let mut yaml_output = String::new(); - for (header, todo_list) in todos { + for (header, todo_list) in todos_map { yaml_output.push_str(&format!("\"{}\":\n", header)); for (line, comment, uscore) in todo_list { @@ -274,17 +228,3 @@ fn out_as_yaml_file(input_csv: String) { println!("{}", yaml_output); } - -fn split_csv(vec: &mut Vec<&str>, split: usize) -> Vec { - let mut rows: Vec = Vec::new(); - - if !vec.is_empty() { - let mut vec2 = vec.split_off(split); - let row = vec.join(","); - rows.push(row); - let mut remaining_rows = split_csv(&mut vec2, split); - rows.append(&mut remaining_rows); - } - - rows -}