srctrait_note_cli/
run.rs

1use std::{borrow::Cow, path::Path, process::ExitCode};
2use clap::Parser;
3use clapx::styl::srctrait::*;
4use clapx::subcmd::cli::CliCommand;
5use srctrait_common_tomlx::starter::trim_starter_toml_file_comments;
6use tomlx::ToStarterToml;
7use crate::*;
8
9pub fn run() -> ExitCode {
10    match run_cli() {
11        Ok(_) => ExitCode::SUCCESS,
12        Err(e) => {
13            let source = e.source()
14                .map_or(String::new(), |s| format!("\n       {s}"));
15
16            eprintln!("{STYL_ERROR}error:{STYL_ERROR:#} {e}{source}");
17            ExitCode::FAILURE
18        }
19    }
20}
21
22fn run_cli() -> anyhow::Result<()> {
23    let cli = Cli::parse();
24    match cli.command {
25        Command::Cli(cmd) => match cmd {
26            CliCommand::Config(_cmd) => run_config(),
27            CliCommand::Alias(_cmd) => todo!(),
28        },
29        Command::Today(cmd) => match &cmd.from {
30            Some(TodaySubCommand::From{when}) => run_today_from(when),
31            None => run_today()
32        },
33        Command::Yesterday => run_yesterday(),
34        Command::Day{when} => run_day(when),
35        Command::Idea{topic} => run_idea(topic),
36        Command::Todo{topic} => run_todo(topic),
37        Command::Plan{topic} => run_plan(topic),
38        Command::Pick{kind} => run_pick(kind),
39    }
40}
41
42fn init_user() -> anyhow::Result<(lib::NoteConfig, lib::NotesDir)> {
43    let config = user_notes_config()?;
44    let dir = user_notes_dir(&config)?;
45    dir.init()?;
46    Ok((config, dir))
47}
48
49fn run_config() -> anyhow::Result<()> {
50    let (config, _notes_dir) = init_user()?;
51    let config_file = note_config_file()?;
52    let first_run = !config_file.is_file();
53
54    if first_run {
55        config.to_starter_toml_file(&config_file, tomlx::starter::GENERIC_INTRO)?;
56    }
57
58    run_editor(&config, &config_file)?;
59
60    if first_run {
61        trim_starter_toml_file_comments(&config_file)?;
62    }
63
64    Ok(())
65}
66
67fn run_today() -> anyhow::Result<()> {
68    let (config, notes_dir) = init_user()?;
69    let note = lib::Note::new(lib::NoteType::Today(lib::Date::now()));
70    let note_file = lib::note_for_date(&notes_dir, &note, None)?;
71    run_editor(&config, &note_file)
72}
73
74fn run_today_from(when: &str) -> anyhow::Result<()> {
75    let (config, notes_dir) = init_user()?;
76    let today = lib::Date::now();
77    let when = today.from(when)?;
78    let note = lib::Note::new(lib::NoteType::Today(today));
79    let note_file = lib::note_for_date(&notes_dir, &note, Some(when))?;
80    run_editor(&config, &note_file)
81}
82
83fn run_day(when: String) -> anyhow::Result<()> {
84    let (config, notes_dir) = init_user()?;
85    let note = lib::Note::new(lib::NoteType::Today(lib::Date::now().from(&when)?));
86    let note_file = lib::note_for_date(&notes_dir, &note, None)?;
87    run_editor(&config, &note_file)
88}
89
90fn run_yesterday() -> anyhow::Result<()> {
91    let (config, notes_dir) = init_user()?;
92    let note = lib::Note::new(lib::NoteType::Today(lib::Date::now().from("yesterday")?));
93    let note_file = lib::note_for_date(&notes_dir, &note, None)?;
94    run_editor(&config, &note_file)
95}
96
97fn run_idea(topic: String) -> anyhow::Result<()> {
98    let (config, notes_dir) = init_user()?;
99    let note = lib::Note::new(lib::NoteType::Idea(topic.to_string()));
100    let note_file = lib::note_for_topic(&notes_dir, &note)?;
101    run_editor(&config, &note_file)
102}
103
104fn run_todo(topic: String) -> anyhow::Result<()> {
105    let (config, notes_dir) = init_user()?;
106    let note = lib::Note::new(lib::NoteType::Todo(topic.to_string()));
107    let note_file = lib::note_for_topic(&notes_dir, &note)?;
108    run_editor(&config, &note_file)
109}
110
111fn run_plan(topic: Option<String>) -> anyhow::Result<()> {
112    let (config, notes_dir) = init_user()?;
113    let note = lib::Note::new(lib::NoteType::Plan(topic));
114    let note_file = lib::note_for_optional_topic(&notes_dir, &note)?;
115    run_editor(&config, &note_file)
116}
117
118fn run_pick(kind: Option<CliNoteKind>) -> anyhow::Result<()> {
119    let (config, notes_dir) = init_user()?;
120    let kind: Option<lib::NoteKind> = kind.map(|k| k.into());
121    let dir: Cow<'_, Path> = if let Some(kind) = kind {
122        Cow::Owned(notes_dir.kind_dir(kind))
123    } else {
124        Cow::Borrowed(&notes_dir)
125    };
126    
127    if let Some(note_path) = run_picker(&config, &dir)? {
128        lib::Note::from_filepath(&notes_dir, &note_path)?;
129        run_editor(&config, &note_path)
130    } else {
131        println!("Cancelled.");
132        Ok(())
133    }
134}