Added subcommand for checking a bartib file

This commit is contained in:
Nikolas Schmidt-Voigt 2021-10-28 08:35:17 +02:00
parent 73f76d9637
commit 904b2552f9
4 changed files with 54 additions and 7 deletions

View file

@ -162,3 +162,11 @@ This is especially useful for autocompletion. For example, adding this line to t
```
complete -W "$(bartib projects)" bartib
```
#### Check bartib file
Checks the bartib file for lines that it can not parse as activities:
```
bartib check
```

View file

@ -42,6 +42,32 @@ pub fn list(file_name: &str, filter: getter::ActivityFilter, do_group_activities
Ok(())
}
// prints all errors that occured when reading the bartib file
pub fn check(file_name: &str) -> Result<()> {
let file_content = bartib_file::get_file_content(file_name)?;
let number_of_errors = file_content.iter()
.filter(|line| line.activity.is_err())
.count();
if number_of_errors == 0 {
println!("All lines in the file have been successfully parsed as activities.");
return Ok(());
}
println!("Found {} line(s) with parsing errors", number_of_errors);
file_content.iter()
.filter(|line| line.activity.is_err() && line.plaintext.is_some())
.for_each(|line| {
if let Err(e) = &line.activity {
println!("\n{}\n -> {} (Line: {})", line.plaintext.as_ref().unwrap(), e.to_string(), line.line_number.unwrap_or(0));
}
});
Ok(())
}
// lists all projects
pub fn list_projects(file_name: &str) -> Result<()> {
let file_content = bartib_file::get_file_content(file_name)?;

View file

@ -17,7 +17,9 @@ pub enum LineStatus {
pub struct Line {
// the plaintext of the line as it has been read from the file
// we save this to be able write untouched lines back to file without chaning them
plaintext: String,
pub plaintext: Option<String>,
// the line number
pub line_number: Option<usize>,
// the result of parsing this line to a activity
pub activity: Result<activity::Activity, activity::ActivityError>,
// the status of this activity
@ -26,9 +28,10 @@ pub struct Line {
impl Line {
// creates a new line struct from plaintext
pub fn new(plaintext: &str) -> Line {
pub fn new(plaintext: &str, line_number: usize) -> Line {
Line {
plaintext: plaintext.trim().to_string(),
plaintext: Some(plaintext.trim().to_string()),
line_number: Some(line_number),
activity: activity::Activity::from_str(plaintext),
status: LineStatus::Unchanged,
}
@ -37,7 +40,8 @@ impl Line {
// creates a new line from an existing activity
pub fn for_activity(activity: activity::Activity) -> Line {
Line {
plaintext: "".to_string(),
plaintext: None,
line_number: None,
activity: Ok(activity),
status: LineStatus::Changed,
}
@ -58,7 +62,8 @@ pub fn get_file_content(file_name: &str) -> Result<Vec<Line>> {
let lines = reader
.lines()
.filter_map(|line_result| line_result.ok())
.map(|line| Line::new(&line))
.enumerate()
.map(|(line_number, line)| Line::new(&line, line_number.saturating_add(1)))
.collect();
Ok(lines)
@ -69,8 +74,14 @@ pub fn write_to_file(file_name: &str, file_content: &[Line]) -> Result<(), io::E
let file_handler = get_bartib_file_writable(file_name)?;
for line in file_content {
match line.status {
LineStatus::Unchanged => writeln!(&file_handler, "{}", line.plaintext)?,
match &line.status {
LineStatus::Unchanged => {
if let Some(plaintext) = &line.plaintext {
writeln!(&file_handler, "{}", plaintext)?
} else {
write!(&file_handler, "{}", line.activity.as_ref().unwrap())?
}
},
LineStatus::Changed => write!(&file_handler, "{}", line.activity.as_ref().unwrap())?,
}
}

View file

@ -192,6 +192,7 @@ fn main() -> Result<()> {
.takes_value(true),
),
)
.subcommand(SubCommand::with_name("check").about("checks file and reports parsing errors"))
.get_matches();
let file_name = matches.value_of("file")
@ -284,6 +285,7 @@ fn run_subcommand(matches: &ArgMatches, file_name: &str) -> Result<()> {
let optional_editor_command = sub_m.value_of("editor");
bartib::controller::manipulation::start_editor(file_name, optional_editor_command)
}
("check", Some(_)) => bartib::controller::list::check(file_name),
_ => bail!("Unknown command"),
}
}