style: code style
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -81,7 +81,6 @@ dependencies = [
|
|||||||
"glob",
|
"glob",
|
||||||
"regex",
|
"regex",
|
||||||
"string-parser",
|
"string-parser",
|
||||||
"string_format",
|
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -291,12 +290,6 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46e079466fad2cd4673f6ccd80b3a2c8aa94e981a7ab7b4e5c023a0a37e23596"
|
checksum = "46e079466fad2cd4673f6ccd80b3a2c8aa94e981a7ab7b4e5c023a0a37e23596"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "string_format"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a0f5f60043c6e865cc477a5cd3981df2210ec02592bd9ba18d32bcd72abb4eb"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|||||||
@@ -18,6 +18,5 @@ colored = "1.9.3"
|
|||||||
string-parser= "0.1.5"
|
string-parser= "0.1.5"
|
||||||
regex = "1.3.9"
|
regex = "1.3.9"
|
||||||
dirs = "2.0.2"
|
dirs = "2.0.2"
|
||||||
string_format = "0.1.0"
|
|
||||||
clap = "2.33.1"
|
clap = "2.33.1"
|
||||||
chrono = "0.4.13"
|
chrono = "0.4.13"
|
||||||
|
|||||||
@@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
> Fork from: https://github.com/ProbablyClem/cargo-todo
|
> Fork from: https://github.com/ProbablyClem/cargo-todo
|
||||||
|
|
||||||
|
> todo comment format:
|
||||||
|
> #1 - priority
|
||||||
|
> !member - member
|
||||||
|
> @2020-01-01 - deadline (format: yyyy/MM/dd or yyyy-MM-dd)
|
||||||
|
>
|
||||||
|
> e.g.
|
||||||
|
> // todo #1 @2020-01-01 !hatter fix it
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
```
|
```
|
||||||
$ cargo install cargo-todo
|
$ cargo install cargo-todo
|
||||||
|
|||||||
135
src/main.rs
135
src/main.rs
@@ -1,9 +1,7 @@
|
|||||||
use std::io::Write;
|
|
||||||
use std::fs::OpenOptions;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{ self, Lines, BufRead, BufReader };
|
use std::io::{ BufRead, BufReader };
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
@@ -18,39 +16,42 @@ use crate::parser::*;
|
|||||||
use crate::regex::regex_parser;
|
use crate::regex::regex_parser;
|
||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
|
|
||||||
|
const BUILD_VER : &str = env!("CARGO_PKG_VERSION");
|
||||||
|
const GIT_HASH : &str = env!("GIT_HASH");
|
||||||
|
const BUILD_DATE: &str = env!("BUILD_DATE");
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
let matches = App::new("Cargo-todo")
|
let matches = App::new("Cargo-todo")
|
||||||
.author("Clément Guiton <clement.guiton.dev@gmail.com>")
|
.author("Clément Guiton <clement.guiton.dev@gmail.com>")
|
||||||
.about("cargo tool to find TODOs in your code")
|
.about("cargo tool to find TODOs in your code")
|
||||||
.arg(Arg::with_name("inline").short("i").long("inline").value_name("inline").takes_value(false).help("display todos in one line"))
|
.arg(Arg::with_name("inline") .short("i").long("inline") .takes_value(false).help("display todos in one line"))
|
||||||
.arg(Arg::with_name("filter").short("f").long("filter").takes_value(true).multiple(true).min_values(1).help("Filter todos to show"))
|
.arg(Arg::with_name("filter") .short("f").long("filter") .takes_value(true).multiple(true).min_values(1).help("Filter todos to show"))
|
||||||
.arg(Arg::with_name("verbose").short("v").long("verbose").multiple(true).help("Sets the level of verbosity"))
|
.arg(Arg::with_name("verbose").short("v").long("verbose").multiple(true).help("Sets the level of verbosity"))
|
||||||
.arg(Arg::with_name("exclude").short("x").long("exclude").takes_value(true).multiple(true).help("Exclude some todos from the list"))
|
.arg(Arg::with_name("exclude").short("x").long("exclude").takes_value(true).multiple(true).help("Exclude some todos from the list"))
|
||||||
.arg(Arg::with_name("list").short("l").long("list").takes_value(true).help("Number of values to display"))
|
.arg(Arg::with_name("list") .short("l").long("list") .takes_value(true).help("Number of values to display"))
|
||||||
.arg(Arg::with_name("sort").short("s").long("sort").takes_value(true).possible_values(&["priority", "deadline", "member", "p", "d", "m"]).help("Sort todos"))
|
.arg(Arg::with_name("sort") .short("s").long("sort") .takes_value(true).possible_values(&["priority", "deadline", "member", "p", "d", "m"]).help("Sort todos"))
|
||||||
.arg(Arg::with_name("member").short("m").long("member").takes_value(true).multiple(true).min_values(1).help("Filter from member"))
|
.arg(Arg::with_name("member") .short("m").long("member") .takes_value(true).multiple(true).min_values(1).help("Filter from member"))
|
||||||
.subcommand(SubCommand::with_name("legacy").about("Launch program in legacy mode (supports todo!(), etc..."))
|
.subcommand(SubCommand::with_name("legacy").about("Launch program in legacy mode (supports todo!(), etc..."))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
if let Some(_) = matches.subcommand_matches("legacy") {
|
if matches.is_present("verbose") {
|
||||||
|
println!("{}\n", include_str!("logo.txt").green().bold());
|
||||||
|
println!("Version : {}", BUILD_VER.underline());
|
||||||
|
println!("Git hash : {}", GIT_HASH.underline());
|
||||||
|
println!("Build date: {}", BUILD_DATE.underline());
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
if matches.subcommand_matches("legacy").is_some() {
|
||||||
main_legacy()
|
main_legacy()
|
||||||
} else {
|
} else {
|
||||||
let mut tokens : Vec<Token> = vec![];
|
let mut tokens: Vec<Token> = vec![];
|
||||||
|
let regex = read_todo_config();
|
||||||
let mut togo_config_path = String::from(dirs::home_dir().unwrap().to_str().unwrap());
|
|
||||||
togo_config_path.push_str("/.cargo/todo_config");
|
|
||||||
let regex = read_lines_to_vec(&togo_config_path);
|
|
||||||
|
|
||||||
let mut all_rs_path = String::from(env::current_dir().unwrap().to_str().unwrap());
|
let mut all_rs_path = String::from(env::current_dir().unwrap().to_str().unwrap());
|
||||||
all_rs_path.push_str("/**/*.rs");
|
all_rs_path.push_str("/**/*.rs");
|
||||||
|
|
||||||
for entry in match glob(&all_rs_path) {
|
for entry in glob(&all_rs_path).unwrap_or_else(|e| panic!("Couldn't access files. Error {}", e)) {
|
||||||
Ok(entry) => entry,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Couldn't access files. Error {}", e);
|
|
||||||
Err(e).unwrap()
|
|
||||||
}
|
|
||||||
} {
|
|
||||||
let path = entry.unwrap();
|
let path = entry.unwrap();
|
||||||
let path = Path::new(&path).strip_prefix(env::current_dir().unwrap().to_str().unwrap()).unwrap();
|
let path = Path::new(&path).strip_prefix(env::current_dir().unwrap().to_str().unwrap()).unwrap();
|
||||||
// println!("{}", path.to_str().unwrap());
|
// println!("{}", path.to_str().unwrap());
|
||||||
@@ -68,53 +69,50 @@ fn main() -> std::io::Result<()> {
|
|||||||
|
|
||||||
if let Some(sort) = matches.value_of("sort") {
|
if let Some(sort) = matches.value_of("sort") {
|
||||||
match sort {
|
match sort {
|
||||||
"p" | "priority" => tokens.sort_unstable_by_key(|t : &Token| -> String {
|
"p" | "priority" => tokens.sort_unstable_by_key(|t: &Token| -> String {
|
||||||
t.priority.clone().unwrap_or_else(|| "z".into())
|
t.priority.clone().unwrap_or_else(|| "z".into())
|
||||||
}),
|
}),
|
||||||
"d" | "deadline" => tokens.sort_unstable_by_key(|t : &Token| -> NaiveDate {
|
"d" | "deadline" => tokens.sort_unstable_by_key(|t: &Token| -> NaiveDate {
|
||||||
t.date.clone().unwrap_or_else(|| NaiveDate::from_ymd(9999, 1, 1))
|
t.date.clone().unwrap_or_else(|| NaiveDate::from_ymd(9999, 1, 1))
|
||||||
}),
|
}),
|
||||||
"m" | "member" => tokens.sort_unstable_by_key(|t : &Token| -> String {
|
"m" | "member" => tokens.sort_unstable_by_key(|t: &Token| -> String {
|
||||||
t.member.clone().unwrap_or_else(|| "zzzzzzzzzzzzz".into())
|
t.member.clone().unwrap_or_else(|| "zzzzzzzzzzzzz".into())
|
||||||
}),
|
}),
|
||||||
_ => {}, // IGNORE
|
_ => {}, // IGNORE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(list) = matches.value_of("list") {
|
|
||||||
let lines = match list.parse::<usize>() {
|
|
||||||
Ok(lines) => lines, Err(_) => {
|
|
||||||
eprintln!("{}", "list argument should be a valid number!".red());
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
tokens = tokens.iter().take(lines).map(|t| t.clone()).collect::<Vec<Token>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(members) = matches.values_of("member") {
|
if let Some(members) = matches.values_of("member") {
|
||||||
let members = members.collect::<HashSet<&str>>();
|
let members = members.collect::<HashSet<&str>>();
|
||||||
tokens = tokens.iter()
|
tokens = tokens.into_iter()
|
||||||
.filter(|t| t.member.as_ref().map(|m| members.contains(m.as_str())).unwrap_or(false))
|
.filter(|t| t.member.as_ref().map(|m| members.contains(m.as_str())).unwrap_or(false))
|
||||||
.map(|t| t.clone())
|
|
||||||
.collect::<Vec<Token>>();
|
.collect::<Vec<Token>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(filters) = matches.values_of("filter") {
|
if let Some(filters) = matches.values_of("filter") {
|
||||||
let filters = filters.collect::<HashSet<&str>>();
|
let filters = filters.collect::<HashSet<&str>>();
|
||||||
tokens = tokens.iter()
|
tokens = tokens.into_iter()
|
||||||
.filter(|t| filters.contains(t.keyword.as_str()))
|
.filter(|t| filters.contains(t.keyword.as_str()))
|
||||||
.map(|t| t.clone())
|
|
||||||
.collect::<Vec<Token>>();
|
.collect::<Vec<Token>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(excludes) = matches.values_of("exclude") {
|
if let Some(excludes) = matches.values_of("exclude") {
|
||||||
let excludes = excludes.collect::<HashSet<&str>>();
|
let excludes = excludes.collect::<HashSet<&str>>();
|
||||||
tokens = tokens.iter()
|
tokens = tokens.into_iter()
|
||||||
.filter(|t| !excludes.contains(t.keyword.as_str()))
|
.filter(|t| !excludes.contains(t.keyword.as_str()))
|
||||||
.map(|t| t.clone())
|
|
||||||
.collect::<Vec<Token>>();
|
.collect::<Vec<Token>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(list) = matches.value_of("list") {
|
||||||
|
let head_count = match list.parse::<usize>() {
|
||||||
|
Ok(head_count) => head_count, Err(_) => {
|
||||||
|
eprintln!("{}", "list argument should be a valid number!".red());
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tokens = tokens.into_iter().take(head_count).collect::<Vec<Token>>();
|
||||||
|
}
|
||||||
|
|
||||||
if matches.is_present("inline") {
|
if matches.is_present("inline") {
|
||||||
tokens.iter().for_each(|i| i.inline());
|
tokens.iter().for_each(|i| i.inline());
|
||||||
} else {
|
} else {
|
||||||
@@ -125,47 +123,38 @@ fn main() -> std::io::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_lines_to_vec(file_name: &str) -> Vec<String> {
|
fn read_todo_config() -> Vec<String> {
|
||||||
let mut regex = vec![];
|
let mut togo_config_path = String::from(dirs::home_dir().unwrap().to_str().unwrap());
|
||||||
for line in read_lines(file_name).unwrap() {
|
togo_config_path.push_str("/.cargo/todo_config");
|
||||||
let line = line.unwrap();
|
let home = dirs::home_dir().unwrap();
|
||||||
if !line.is_empty() { regex.push(line) };
|
let home_todo_config = home.join(".cargo").join("todo_config");
|
||||||
|
if !home_todo_config.exists() {
|
||||||
|
return vec![
|
||||||
|
r"^\s*//\s*todo\b".into(),
|
||||||
|
r"^\s*//\s*fix\b".into(),
|
||||||
|
r"^\s*//\s*fixme\b".into(),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
return regex;
|
BufReader::new(File::open(home_todo_config).unwrap()).lines().map(|ln| ln.unwrap()).collect()
|
||||||
}
|
|
||||||
|
|
||||||
fn read_lines<P>(filename: P) -> io::Result<Lines<BufReader<File>>> where P: AsRef<Path> {
|
|
||||||
let file = match File::open(&filename) {
|
|
||||||
Ok(line) => line,
|
|
||||||
Err(_) => {
|
|
||||||
println!("{}", "File '~/.cargo/todo_config' not found, creating it".red());
|
|
||||||
let mut f = OpenOptions::new().write(true).read(true).create(true).open(&filename).unwrap();
|
|
||||||
f.write_all(b"^s*//s*todo\\b\n").unwrap();
|
|
||||||
f.write_all(b"^s*//s*fix\\b\n").unwrap();
|
|
||||||
f.write_all(b"^s*//s*fixme\\b\n").unwrap();
|
|
||||||
return read_lines(filename);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(BufReader::new(file).lines())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main_legacy() -> std::io::Result<()> {
|
fn main_legacy() -> std::io::Result<()> {
|
||||||
let mut parsers : Vec<Parser> = vec![];
|
let mut parsers : Vec<Parser> = vec![];
|
||||||
|
|
||||||
let mut path = String::from(env::current_dir().unwrap().to_str().unwrap());
|
let mut path = String::from(env::current_dir().unwrap().to_str().unwrap());
|
||||||
path.push_str("/**/*.rs");
|
path.push_str("/**/*.rs");
|
||||||
|
|
||||||
//we add a parser looking for the //todo keyword
|
//we add a parser looking for the //todo keyword
|
||||||
parsers.push(Parser::new(String::from("//todo"), Box::from(|x : Vec<char>| x.last().unwrap() == &'\n')));
|
parsers.push(Parser::new(String::from("//todo"), Box::from(|x: Vec<char>| x.last().unwrap() == &'\n')));
|
||||||
//we add a parser looking for the todo!() token
|
//we add a parser looking for the todo!() token
|
||||||
let todo_macro_callback = Box::from(|mut text : String, line : usize, file : &str| {
|
let todo_macro_callback = Box::from(|mut text: String, line: usize, file: &str| {
|
||||||
text.retain(|c| c != '\"');
|
text.retain(|c| c != '\"');
|
||||||
println!("{} {} {} {} : {}",file,"TODO".green() ,"Line ".green(), line.to_string().green(), text.blue());
|
println!("{} {} {} {} : {}", file, "TODO".green(), "Line ".green(), line.to_string().green(), text.blue());
|
||||||
});
|
});
|
||||||
parsers.push(Parser::new_callback(String::from("todo!("), Box::from(|x : Vec<char>| x.last().unwrap() == &')'), todo_macro_callback));
|
parsers.push(Parser::new_callback(String::from("todo!("), Box::from(|x : Vec<char>| x.last().unwrap() == &')'), todo_macro_callback));
|
||||||
|
|
||||||
//support for unimplemented
|
//support for unimplemented
|
||||||
let unimplemented_macro_callback = Box::from(|text : String, line : usize, file : &str| {
|
let unimplemented_macro_callback = Box::from(|text: String, line: usize, file: &str| {
|
||||||
println!("{} {} {} {} : {}{}{} ", file, "TODO".green(), "Line ".green(), line.to_string().green(), "unimplemented!(".blue(), text.magenta(), ")".blue());
|
println!("{} {} {} {} : {}{}{} ", file, "TODO".green(), "Line ".green(), line.to_string().green(), "unimplemented!(".blue(), text.magenta(), ")".blue());
|
||||||
});
|
});
|
||||||
parsers.push(Parser::new_callback(String::from("unimplemented!("), Box::from(|x : Vec<char>| x.last().unwrap() == &')'), unimplemented_macro_callback));
|
parsers.push(Parser::new_callback(String::from("unimplemented!("), Box::from(|x : Vec<char>| x.last().unwrap() == &')'), unimplemented_macro_callback));
|
||||||
@@ -173,13 +162,7 @@ fn main_legacy() -> std::io::Result<()> {
|
|||||||
parsers.push(Parser::new(String::from("//fix"), Box::from(|x : Vec<char>| x.last().unwrap() == &'\n')));
|
parsers.push(Parser::new(String::from("//fix"), Box::from(|x : Vec<char>| x.last().unwrap() == &'\n')));
|
||||||
|
|
||||||
//loop on every file within the current dir
|
//loop on every file within the current dir
|
||||||
for entry in match glob(&path) {
|
for entry in glob(&path).unwrap_or_else(|e| panic!("Couldn't access files. Error {}", e)) {
|
||||||
Ok(entry) => entry,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Couldn't access files. Error {}", e);
|
|
||||||
Err(e).unwrap()
|
|
||||||
}
|
|
||||||
} {
|
|
||||||
let path = entry.unwrap();
|
let path = entry.unwrap();
|
||||||
let path = Path::new(&path).strip_prefix(env::current_dir().unwrap().to_str().unwrap()).unwrap();
|
let path = Path::new(&path).strip_prefix(env::current_dir().unwrap().to_str().unwrap()).unwrap();
|
||||||
if !path.starts_with("target/") {
|
if !path.starts_with("target/") {
|
||||||
@@ -200,10 +183,12 @@ fn main_legacy() -> std::io::Result<()> {
|
|||||||
//todo implement @2001/11/01 #3 getters !clement
|
//todo implement @2001/11/01 #3 getters !clement
|
||||||
//todo implement @2001-11-01 #3 getters !thomas
|
//todo implement @2001-11-01 #3 getters !thomas
|
||||||
//fix implement @18/11/2001 getters !jht5945
|
//fix implement @18/11/2001 getters !jht5945
|
||||||
|
// todo this is hatter sample test
|
||||||
|
// todo
|
||||||
//4
|
//4
|
||||||
//10/10/10
|
//10/10/10
|
||||||
fn test(){
|
fn test(){
|
||||||
todo!("implements getters");
|
todo!("implements getters XXX !!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo implement @2020/08/14 #5 getters !clement
|
//todo implement @2020/08/14 #5 getters !clement
|
||||||
@@ -13,7 +13,7 @@ impl Parser {
|
|||||||
// let path = Path::new(file).strip_prefix(env::current_dir().unwrap().to_str().unwrap()).unwrap();
|
// let path = Path::new(file).strip_prefix(env::current_dir().unwrap().to_str().unwrap()).unwrap();
|
||||||
println!("{} {} {} {} : {}", file, "TODO".green() ,"Line ".green(), line.to_string().green(), text.blue());
|
println!("{} {} {} {} : {}", file, "TODO".green() ,"Line ".green(), line.to_string().green(), text.blue());
|
||||||
});
|
});
|
||||||
Parser{ keyword, end_filter, callback }
|
Parser { keyword, end_filter, callback }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_callback(keyword: String, end_filter: Box<dyn Fn(Vec<char>) -> bool>, callback: Box<dyn Fn(String, usize, &str)>) -> Parser {
|
pub fn new_callback(keyword: String, end_filter: Box<dyn Fn(Vec<char>) -> bool>, callback: Box<dyn Fn(String, usize, &str)>) -> Parser {
|
||||||
|
|||||||
@@ -6,18 +6,20 @@ use crate::token::*;
|
|||||||
|
|
||||||
// The output is wrapped in a Result to allow matching on errors
|
// The output is wrapped in a Result to allow matching on errors
|
||||||
// Returns an Iterator to the Reader of the lines of the file.
|
// Returns an Iterator to the Reader of the lines of the file.
|
||||||
fn read_lines<P>(filename: P) -> io::Result<Lines<BufReader<File>>> where P: AsRef<Path>, {
|
fn read_lines<P>(filename: P) -> io::Result<Lines<BufReader<File>>> where P: AsRef<Path> {
|
||||||
let file = File::open(filename)?;
|
let file = File::open(filename)?;
|
||||||
Ok(BufReader::new(file).lines())
|
Ok(BufReader::new(file).lines())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn regex_parser(path: &str, regex: &[String], verbosity: i8) -> Result<Vec<Token>, io::Error> {
|
pub fn regex_parser(path: &str, regex: &[String], verbosity: i8) -> Result<Vec<Token>, io::Error> {
|
||||||
let set = RegexSet::new(regex).unwrap();
|
let set = RegexSet::new(regex).unwrap_or_else(|e| panic!("Parse regex set: {:?}, failed: {}", regex, e));
|
||||||
|
// println!("+++ {:?}", set);
|
||||||
let mut tokens = vec![];
|
let mut tokens = vec![];
|
||||||
for (line_cpt, line) in (read_lines(path)?).enumerate() {
|
for (line_cpt, line) in (read_lines(path)?).enumerate() {
|
||||||
let line_cpt_from1 = line_cpt + 1;
|
let line_cpt_from1 = line_cpt + 1;
|
||||||
let line = line.unwrap();
|
let line = line.unwrap();
|
||||||
if set.is_match(line.to_lowercase().as_str()) {
|
if set.is_match(line.to_lowercase().as_str()) {
|
||||||
|
// println!("+++ {}", line);
|
||||||
tokens.push(Token::new(path.to_string(), line_cpt_from1, line, verbosity));
|
tokens.push(Token::new(path.to_string(), line_cpt_from1, line, verbosity));
|
||||||
// println!("{}", t);
|
// println!("{}", t);
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/token.rs
22
src/token.rs
@@ -15,13 +15,21 @@ pub struct Token{
|
|||||||
verbosity: i8,
|
verbosity: i8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// priority, format #1
|
||||||
|
const NUMBER_REGEX: &str = r"#[0-9]";
|
||||||
|
// deadline, format @2020-01-01
|
||||||
|
const DATE_REGEX: &str = r"@(\d{4})[/\-](\d{2})[/\-](\d{2})";
|
||||||
|
// member, format !hatter
|
||||||
|
const MEMBER_REGEX: &str = r"![\w]+";
|
||||||
|
|
||||||
impl Token {
|
impl Token {
|
||||||
pub fn new(file: String, line: usize, s: String, verbosity: i8) -> Token {
|
pub fn new(file: String, line: usize, s: String, verbosity: i8) -> Token {
|
||||||
// println!(">>>>>>>>>>>{}", s);
|
// println!(">>>>>>>>>>>{}", s);
|
||||||
let fields: Vec<&str>= s.split_whitespace().collect();
|
let s = s.trim().chars().skip(2).collect::<String>(); // remove leading "//"
|
||||||
let number_regex = Regex::new(r"#[0-9]").unwrap();
|
let fields = s.trim().split_whitespace().collect::<Vec<&str>>();
|
||||||
let date_regex = Regex::new(r"@(\d{4})[/\-](\d{2})[/\-](\d{2})").unwrap();
|
let number_regex = Regex::new(NUMBER_REGEX).unwrap();
|
||||||
let member_regex = Regex::new(r"![\w]+").unwrap();
|
let date_regex = Regex::new(DATE_REGEX).unwrap();
|
||||||
|
let member_regex = Regex::new(MEMBER_REGEX).unwrap();
|
||||||
// println!("///////////{:?}", fields);
|
// println!("///////////{:?}", fields);
|
||||||
|
|
||||||
let mut t = Token {
|
let mut t = Token {
|
||||||
@@ -58,7 +66,7 @@ impl Token {
|
|||||||
|
|
||||||
pub fn inline(&self) {
|
pub fn inline(&self) {
|
||||||
let mut inline_msg = vec![
|
let mut inline_msg = vec![
|
||||||
format!("{} line: {:>4} {:<6} ", self.file, self.line.to_string().green(), self.keyword.clone().green())
|
format!("{} line: {} {} ", self.file, self.line.to_string().green(), self.keyword.green().bold())
|
||||||
];
|
];
|
||||||
if let Some(member) = &self.member {
|
if let Some(member) = &self.member {
|
||||||
inline_msg.push(format!("member: {}", member.red()));
|
inline_msg.push(format!("member: {}", member.red()));
|
||||||
@@ -67,6 +75,7 @@ impl Token {
|
|||||||
inline_msg.push(format!("priority: {}", priority.red()));
|
inline_msg.push(format!("priority: {}", priority.red()));
|
||||||
}
|
}
|
||||||
if let Some(date) = &self.date {
|
if let Some(date) = &self.date {
|
||||||
|
// TODO display deadline vs current time inline !hatter
|
||||||
inline_msg.push(format!("deadline: {}", date.to_string().red()));
|
inline_msg.push(format!("deadline: {}", date.to_string().red()));
|
||||||
}
|
}
|
||||||
if let Some(comment) = &self.comment {
|
if let Some(comment) = &self.comment {
|
||||||
@@ -94,6 +103,7 @@ impl fmt::Display for Token {
|
|||||||
multiline_msg.push(format!("- priority: {}", priority.red()));
|
multiline_msg.push(format!("- priority: {}", priority.red()));
|
||||||
}
|
}
|
||||||
if let Some(date) = &self.date {
|
if let Some(date) = &self.date {
|
||||||
|
// TODO display deadline vs current time !hatter
|
||||||
multiline_msg.push(format!("- deadline: {}", date.to_string().red()));
|
multiline_msg.push(format!("- deadline: {}", date.to_string().red()));
|
||||||
}
|
}
|
||||||
if let Some(comment) = &self.comment {
|
if let Some(comment) = &self.comment {
|
||||||
@@ -101,7 +111,7 @@ impl fmt::Display for Token {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, "{}\n", multiline_msg.join("\n"))?;
|
writeln!(f, "{}", multiline_msg.join("\n"))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user