Adapt cli code to changes

This commit is contained in:
Joscha 2022-01-06 18:04:34 +01:00
parent 5e47dddd4c
commit 3f5e06b113
10 changed files with 101 additions and 90 deletions

View file

@ -7,20 +7,19 @@ use codespan_reporting::files::SimpleFile;
use directories::ProjectDirs;
use structopt::StructOpt;
use crate::error;
// use crate::eval::{DateRange, Entry, EntryMode, SourceInfo};
use crate::eval::{DateRange, Entry, EntryMode};
use crate::files::arguments::Range;
use crate::files::{self, Files};
use crate::files::{self, FileSource, Files};
// use self::error::Result;
// use self::layout::line::LineLayout;
use self::error::Error;
use self::layout::line::LineLayout;
// mod cancel;
// mod done;
// mod error;
// mod layout;
// mod print;
// mod show;
mod cancel;
mod done;
mod error;
mod layout;
mod print;
mod show;
#[derive(Debug, StructOpt)]
pub struct Opt {
@ -83,9 +82,7 @@ fn find_now(opt: &Opt, files: &Files) -> NaiveDateTime {
}
}
/*
fn find_entries(files: &Files, range: DateRange) -> Result<Vec<Entry>> {
fn find_entries(files: &Files, range: DateRange) -> Result<Vec<Entry>, Error<FileSource>> {
Ok(files.eval(EntryMode::Relevant, range)?)
}
@ -98,7 +95,12 @@ fn find_layout(
layout::layout(files, entries, range, now)
}
fn run_command(opt: &Opt, files: &mut Files, range: DateRange, now: NaiveDateTime) -> Result<()> {
fn run_command(
opt: &Opt,
files: &mut Files,
range: DateRange,
now: NaiveDateTime,
) -> Result<(), Error<FileSource>> {
match &opt.command {
None => {
let entries = find_entries(files, range)?;
@ -131,14 +133,12 @@ fn run_command(opt: &Opt, files: &mut Files, range: DateRange, now: NaiveDateTim
Ok(())
}
*/
pub fn run() {
let opt = Opt::from_args();
let mut files = Files::new();
if let Err(e) = load_files(&opt, &mut files) {
error::eprint_error(&files, &e);
crate::error::eprint_error(&files, &e);
process::exit(1);
}
@ -151,7 +151,7 @@ pub fn run() {
Err(e) => {
eprintln!("Failed to evaluate --range:");
let file = SimpleFile::new("--range", &opt.range);
error::eprint_error(&file, &e);
crate::error::eprint_error(&file, &e);
process::exit(1)
}
},
@ -161,17 +161,13 @@ pub fn run() {
}
};
/*
if let Err(e) = run_command(&opt, &mut files, range, now) {
e.print(&files.sources());
crate::error::eprint_error(&files, &e);
process::exit(1);
}
*/
if let Err(e) = files.save() {
error::eprint_error(&files, &e);
crate::error::eprint_error(&files, &e);
process::exit(1);
}
}

View file

@ -6,16 +6,16 @@ use crate::eval::Entry;
use crate::files::commands::{Done, DoneKind};
use crate::files::Files;
use super::error::{Error, Result};
use super::error::Error;
use super::layout::line::LineLayout;
pub fn cancel(
pub fn cancel<S>(
files: &mut Files,
entries: &[Entry],
layout: &LineLayout,
numbers: &[usize],
now: NaiveDateTime,
) -> Result<()> {
) -> Result<(), Error<S>> {
let mut not_tasks = vec![];
for &number in numbers {
let entry = &entries[layout.look_up_number(number)?];

View file

@ -6,16 +6,16 @@ use crate::eval::Entry;
use crate::files::commands::{Done, DoneKind};
use crate::files::Files;
use super::error::{Error, Result};
use super::error::Error;
use super::layout::line::LineLayout;
pub fn done(
pub fn done<S>(
files: &mut Files,
entries: &[Entry],
layout: &LineLayout,
numbers: &[usize],
now: NaiveDateTime,
) -> Result<()> {
) -> Result<(), Error<S>> {
let mut not_tasks = vec![];
for &number in numbers {
let entry = &entries[layout.look_up_number(number)?];

View file

@ -1,21 +1,25 @@
use std::result;
use crate::eval::{self, SourceInfo};
use codespan_reporting::files::Files;
use codespan_reporting::term::Config;
use crate::error::Eprint;
use crate::eval;
#[derive(Debug, thiserror::Error)]
pub enum Error {
pub enum Error<S> {
#[error("{0}")]
Eval(#[from] eval::Error),
Eval(#[from] eval::Error<S>),
#[error("No entry with number {0}")]
NoSuchEntry(usize),
#[error("Not a task")]
NotATask(Vec<usize>),
}
impl Error {
pub fn print<'a>(&self, sources: &[SourceInfo<'a>]) {
impl<'a, F: Files<'a>> Eprint<'a, F> for Error<F::FileId> {
fn eprint<'f: 'a>(&self, files: &'f F, config: &Config) {
match self {
Error::Eval(e) => e.print(sources),
Error::Eval(e) => e.eprint(files, config),
Error::NoSuchEntry(n) => eprintln!("No entry with number {}", n),
Error::NotATask(ns) => {
if ns.is_empty() {
@ -30,5 +34,3 @@ impl Error {
}
}
}
pub type Result<T> = result::Result<T, Error>;

View file

@ -8,7 +8,6 @@ use std::collections::HashMap;
use chrono::{NaiveDate, NaiveDateTime};
use crate::eval::{DateRange, Dates, Entry, EntryKind};
use crate::files::commands::Command;
use crate::files::primitives::Time;
use crate::files::Files;
@ -51,15 +50,10 @@ impl DayLayout {
pub fn layout(&mut self, files: &Files, entries: &[Entry]) {
self.insert(self.today, DayEntry::Now(self.time));
let mut commands = entries
.iter()
.enumerate()
.map(|(i, e)| (i, e, files.command(e.source)))
.collect::<Vec<_>>();
let mut entries = entries.iter().enumerate().collect::<Vec<_>>();
Self::sort_entries(&mut entries);
Self::sort_entries(&mut commands);
for (index, entry, _) in commands {
for (index, entry) in entries {
self.layout_entry(index, entry);
}
@ -196,7 +190,7 @@ impl DayLayout {
}
}
fn sort_entries(entries: &mut Vec<(usize, &Entry, &Command)>) {
fn sort_entries(entries: &mut Vec<(usize, &Entry)>) {
// Entries should be sorted by these factors, in descending order of
// significance:
// 1. Their start date, if any
@ -205,10 +199,10 @@ impl DayLayout {
// 4. Their title
// 4.
entries.sort_by_key(|(_, _, c)| c.title());
entries.sort_by_key(|(_, e)| &e.title);
// 3.
entries.sort_by_key(|(_, e, _)| match e.kind {
entries.sort_by_key(|(_, e)| match e.kind {
EntryKind::Task => 0,
EntryKind::TaskDone(_) | EntryKind::TaskCanceled(_) => 1,
EntryKind::Birthday(_) => 2,
@ -216,14 +210,14 @@ impl DayLayout {
});
// 2.
entries.sort_by(|(_, e1, _), (_, e2, _)| {
entries.sort_by(|(_, e1), (_, e2)| {
let d1 = e1.dates.map(|d| d.sorted().other_with_time());
let d2 = e2.dates.map(|d| d.sorted().other_with_time());
d2.cmp(&d1) // Inverse comparison
});
// 1.
entries.sort_by_key(|(_, e, _)| e.dates.map(|d| d.sorted().root_with_time()));
entries.sort_by_key(|(_, e)| e.dates.map(|d| d.sorted().root_with_time()));
}
fn sort_day(day: &mut Vec<DayEntry>) {

View file

@ -11,7 +11,7 @@ use crate::eval::{Entry, EntryKind};
use crate::files::primitives::Time;
use crate::files::Files;
use super::super::error::{Error, Result};
use super::super::error::Error;
use super::day::{DayEntry, DayLayout};
#[derive(Debug, Clone, Copy)]
@ -145,7 +145,7 @@ impl LineLayout {
&self.lines
}
pub fn look_up_number(&self, number: usize) -> Result<usize> {
pub fn look_up_number<S>(&self, number: usize) -> Result<usize, Error<S>> {
self.numbers
.iter()
.filter(|(_, n)| **n == number)
@ -253,10 +253,10 @@ impl LineLayout {
}
fn entry_title(files: &Files, entry: &Entry) -> String {
let command = files.command(entry.source);
let command = files.command(entry.source).command;
match entry.kind {
EntryKind::Birthday(Some(age)) => format!("{} ({})", command.title(), age),
_ => command.title().to_string(),
EntryKind::Birthday(Some(age)) => format!("{} ({})", entry.title, age),
_ => entry.title.clone(),
}
}

View file

@ -1,32 +1,18 @@
use crate::eval::{Entry, EntryKind};
use crate::files::Files;
use super::error::Result;
use super::error::Error;
use super::layout::line::LineLayout;
fn show_entry(files: &Files, entry: &Entry) {
let command = files.command(entry.source);
match entry.kind {
EntryKind::Task => println!("TASK {}", command.title()),
EntryKind::TaskDone(when) => {
println!("DONE {}", command.title());
println!("DONE AT {}", when);
}
EntryKind::TaskCanceled(when) => {
println!("CANCELED {}", command.title());
println!("CANCELED AT {}", when);
}
EntryKind::Note => println!("NOTE {}", command.title()),
EntryKind::Birthday(Some(age)) => {
println!("BIRTHDAY {}", command.title());
println!("AGE {}", age);
}
EntryKind::Birthday(None) => {
println!("BIRTHDAY {}", command.title());
println!("AGE UNKNOWN");
}
}
let kind = match entry.kind {
EntryKind::Task | EntryKind::TaskDone(_) | EntryKind::TaskCanceled(_) => "TASK",
EntryKind::Note => "NOTE",
EntryKind::Birthday(_) => "BIRTHDAY",
};
println!("{} {}", kind, entry.title);
if let Some(dates) = entry.dates {
println!("DATE {}", dates.sorted());
@ -34,17 +20,25 @@ fn show_entry(files: &Files, entry: &Entry) {
println!("NO DATE");
}
for line in command.desc() {
println!("# {}", line);
match entry.kind {
EntryKind::TaskDone(when) => println!("DONE {}", when),
EntryKind::TaskCanceled(when) => println!("CANCELED {}", when),
EntryKind::Birthday(Some(age)) => println!("AGE {}", age),
_ => {}
}
println!("FROM COMMAND");
for line in format!("{}", command.command).lines() {
println!("| {}", line);
}
}
pub fn show(
pub fn show<S>(
files: &Files,
entries: &[Entry],
layout: &LineLayout,
numbers: &[usize],
) -> Result<()> {
) -> Result<(), Error<S>> {
if numbers.is_empty() {
// Nothing to do
return Ok(());
@ -53,7 +47,7 @@ pub fn show(
let indices = numbers
.iter()
.map(|n| layout.look_up_number(*n))
.collect::<Result<Vec<usize>>>()?;
.collect::<Result<Vec<usize>, _>>()?;
show_entry(files, &entries[indices[0]]);
for &index in indices.iter().skip(1) {

View file

@ -45,6 +45,20 @@ impl<'a> EvalCommand<'a> {
}
}
fn title(&self) -> String {
match self {
Self::Task(task) => task.title.clone(),
Self::Note(note) => note.title.clone(),
}
}
fn has_description(&self) -> bool {
match self {
Self::Task(task) => !task.desc.is_empty(),
Self::Note(note) => !note.desc.is_empty(),
}
}
/// Last root date mentioned in any `DONE`.
fn last_done_root(&self) -> Option<NaiveDate> {
match self {
@ -172,7 +186,14 @@ impl<'a> CommandState<'a> {
None
};
Ok(Entry::new(self.source, kind, dates, remind))
Ok(Entry::new(
self.source,
kind,
self.command.title(),
self.command.has_description(),
dates,
remind,
))
}
/// Add an entry, respecting [`Self::from`] and [`Self::until`]. Does not

View file

@ -15,10 +15,12 @@ pub enum EntryKind {
}
/// A single instance of a command.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone)]
pub struct Entry {
pub source: Source,
pub kind: EntryKind,
pub title: String,
pub has_description: bool,
pub dates: Option<Dates>,
/// Remind the user of an entry before it occurs. This date should always be
/// before the entry's start date, or `None` if there is no start date.
@ -29,6 +31,8 @@ impl Entry {
pub fn new(
source: Source,
kind: EntryKind,
title: String,
has_description: bool,
dates: Option<Dates>,
remind: Option<NaiveDate>,
) -> Self {
@ -43,6 +47,8 @@ impl Entry {
Self {
source,
kind,
title,
has_description,
dates,
remind,
}

View file

@ -7,7 +7,7 @@ use chrono::{DateTime, NaiveDate, Utc};
use codespan_reporting::files::SimpleFiles;
use tzfile::Tz;
use self::commands::{Command, File};
use self::commands::{Command, Done, File};
pub use self::error::{Error, Result};
use self::primitives::Spanned;
@ -337,7 +337,6 @@ impl Files {
}
}
/*
/// Add a [`Done`] statement to the task identified by `source`.
///
/// Returns whether the addition was successful. It can fail if the entry
@ -347,12 +346,11 @@ impl Files {
let file = &mut self.files[source.file];
match &mut file.file.commands[source.command] {
Command::Task(t) => t.done.push(done),
Command::Note(_) => return false,
_ => return false,
}
file.dirty = true;
true
}
*/
/* Errors */