1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
use anyhow::Result;
use std::fs;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
use thiserror::Error;
#[derive(Debug, StructOpt)]
#[structopt(about = "maintain a journal")]
enum JT {
Init {
#[structopt(help = "Directory where journal should be stored")]
dirname: PathBuf,
#[structopt(help = "Short name for journal")]
journalname: String,
#[structopt(help = "Short description of journal, its title")]
description: String,
},
IsJournal {
#[structopt(help = "Directory that may or may not be a journal")]
dirname: PathBuf,
},
New {
#[structopt(long, short, help = "Use DIRNAME as the location of the journal")]
dirname: PathBuf,
#[structopt(
long,
short,
help = "Invoke EDITOR for user to edit draft",
default_value = "/usr/bin/editor"
)]
editor: String,
#[structopt(help = "Title of new draft")]
title: String,
},
Finish {
#[structopt(long, short, help = "Use DIRNAME as the location of the journal")]
dirname: PathBuf,
},
}
#[derive(Debug, Error)]
enum JournalError {
#[error("directory {0} is not a journal")]
NotAJournal(String),
}
fn main() -> Result<()> {
let opt = JT::from_args();
match opt {
JT::Init {
dirname,
journalname,
description,
} => init(&dirname, &journalname, &description)?,
JT::IsJournal { dirname } => is_journal(&dirname)?,
JT::New {
title,
dirname,
editor,
} => new_draft(&title, &dirname, &editor)?,
JT::Finish { dirname } => finish_draft(&dirname)?,
}
Ok(())
}
fn init(dirname: &Path, _journalname: &str, _description: &str) -> anyhow::Result<()> {
std::fs::create_dir(dirname)?;
Ok(())
}
fn is_journal(dirname: &Path) -> anyhow::Result<()> {
let meta = fs::symlink_metadata(dirname)?;
if !meta.is_dir() {
return Err(JournalError::NotAJournal(dirname.display().to_string()).into());
}
Ok(())
}
fn new_draft(title: &str, dirname: &Path, editor: &str) -> anyhow::Result<()> {
let drafts = dirname.join("drafts");
if !drafts.exists() {
std::fs::create_dir(&drafts)?;
}
let draft_filename = drafts.join("0.md");
std::fs::write(draft_filename, title)?;
Ok(())
}
fn finish_draft(dirname: &Path) -> anyhow::Result<()> {
let drafts = dirname.join("drafts");
let draft = drafts.join("0.md");
let entries = dirname.join("entries");
if !entries.exists() {
std::fs::create_dir(&entries)?;
}
let entry = entries.join("0.md");
std::fs::rename(draft, entry)?;
Ok(())
}
|