108 lines
3.3 KiB
Rust
108 lines
3.3 KiB
Rust
use chrono::NaiveDate;
|
|
use codespan_reporting::files::Files as CsFiles;
|
|
use colored::Colorize;
|
|
|
|
use crate::eval::{Entry, EntryKind};
|
|
use crate::files::commands::{Command, Log};
|
|
use crate::files::primitives::Spanned;
|
|
use crate::files::{Files, Sourced};
|
|
|
|
use super::error::Error;
|
|
use super::layout::line::LineLayout;
|
|
use super::util;
|
|
|
|
fn fmt_where(files: &Files, command: &Sourced<'_, Spanned<Command>>) -> String {
|
|
let name = files.name(command.source.file()).expect("file exists");
|
|
let line = files
|
|
.line_index(command.source.file(), command.value.span.start)
|
|
.expect("file exists and line is valid");
|
|
let line = line + 1; // 1-indexed for human consumption
|
|
format!("Line {line} in {name}")
|
|
}
|
|
|
|
fn print_desc(command: &Sourced<'_, Spanned<Command>>) {
|
|
let desc: &[String] = match &command.value.value {
|
|
Command::Task(task) => &task.desc,
|
|
Command::Note(note) => ¬e.desc,
|
|
Command::Log(log) => &log.desc,
|
|
_ => &[],
|
|
};
|
|
if !desc.is_empty() {
|
|
println!();
|
|
for line in desc {
|
|
println!("{}", line);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn show_entry(files: &Files, entry: &Entry) {
|
|
let command = files.command(entry.source);
|
|
|
|
let kind = util::display_kind(LineLayout::entry_kind(entry));
|
|
println!("{} {} {}", "Title:".bright_black(), kind, entry.title);
|
|
|
|
let what = match entry.kind {
|
|
EntryKind::Task => "Task".to_string(),
|
|
EntryKind::TaskDone(date) => format!("Task, done {date}"),
|
|
EntryKind::TaskCanceled(date) => format!("Task, canceled {date}"),
|
|
EntryKind::Note => "Note".to_string(),
|
|
EntryKind::Birthday(None) => "Birthday, age unknown".to_string(),
|
|
EntryKind::Birthday(Some(age)) => format!("Birthday, age {age}"),
|
|
};
|
|
println!("{} {}", "What:".bright_black(), what);
|
|
|
|
let when = match entry.dates {
|
|
None => "no date".to_string(),
|
|
Some(date) => format!("{}", date.sorted()),
|
|
};
|
|
println!("{} {}", "When:".bright_black(), when);
|
|
|
|
println!("{} {}", "Where:".bright_black(), fmt_where(files, &command));
|
|
|
|
print_desc(&command);
|
|
}
|
|
|
|
fn show_log(files: &Files, log: Sourced<'_, Log>) {
|
|
let command = files.command(log.source);
|
|
|
|
println!("{} Log entry", "What:".bright_black());
|
|
println!("{} {}", "When:".bright_black(), log.value.date);
|
|
|
|
println!("{} {}", "Where:".bright_black(), fmt_where(files, &command));
|
|
|
|
print_desc(&command);
|
|
}
|
|
|
|
fn show_ident(files: &Files, entries: &[Entry], layout: &LineLayout, ident: Ident) {
|
|
match ident {
|
|
Ident::Number(n) => match layout.look_up_number(n) {
|
|
Ok(index) => show_entry(files, &entries[index]),
|
|
Err(e) => println!("{e}"),
|
|
},
|
|
Ident::Date(date) => match files.log(date) {
|
|
Some(log) => show_log(files, log),
|
|
None => println!("{}", Error::NoSuchLog(date)),
|
|
},
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub enum Ident {
|
|
Number(usize),
|
|
Date(NaiveDate),
|
|
}
|
|
|
|
pub fn show(files: &Files, entries: &[Entry], layout: &LineLayout, idents: &[Ident]) {
|
|
if idents.is_empty() {
|
|
// Nothing to do
|
|
return;
|
|
}
|
|
|
|
show_ident(files, entries, layout, idents[0]);
|
|
for &ident in idents.iter().skip(1) {
|
|
println!();
|
|
println!();
|
|
println!();
|
|
show_ident(files, entries, layout, ident);
|
|
}
|
|
}
|