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
|
use chrono::naive::NaiveDate;
use rust_decimal::Decimal;
use std::path::PathBuf;
use std::str::FromStr;
use structopt::StructOpt;
mod store;
mod transaction;
//TODO relative ("yesterday", "-2d", etc)
fn parse_date(s: &str) -> Result<NaiveDate, String> {
NaiveDate::parse_from_str(s, "%Y-%m-%d").map_err(|e| e.to_string())
}
#[derive(Debug)]
#[derive(StructOpt)]
enum Command {
Insert {
kind: transaction::TransactionKind,
#[structopt(long)]
account: String,
// #[structopt(long = "category", multiple = true, number_of_values = 1)]
// category: Vec<String>,
#[structopt(long)]
category: String,
#[structopt(long, parse(try_from_str = Decimal::from_str))]
amount: Decimal,
description: String,
#[structopt(long, parse(try_from_str = parse_date))]
date: Option<NaiveDate>,
},
List {
target: ListTarget,
}
}
#[derive(Debug)]
#[derive(StructOpt)]
enum ListTarget {
Categories,
}
impl std::str::FromStr for ListTarget {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"categories" => Ok(ListTarget::Categories),
_ => Err(format!("Unknown listable: {:?}", s)),
}
}
}
#[derive(Debug)]
#[derive(StructOpt)]
struct Mn {
#[structopt(subcommand)]
command: Command,
}
fn main() {
let mut store = store::Store::open(PathBuf::from("store")).unwrap();
let args = Mn::from_args();
eprintln!("{:?}", args);
match args.command {
Command::Insert {
kind,
account,
category,
amount,
description,
date,
} => {
let transaction = transaction::Transaction {
kind,
to: account,
from: "Default".to_string(),
category,
amount,
description,
date: match date {
Some(date) => date,
None => chrono::offset::Local::today().naive_utc(),
},
};
eprintln!("{:?}", transaction);
println!("{}", transaction.id());
store.push(transaction);
store.write().unwrap();
}
Command::List {
target: ListTarget::Categories
} => {
println!("{:?}", store.categories());
}
}
}
|