From 92e0848d4075e9b5ed11726d8d62e687d7fc673c Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Mon, 17 May 2021 12:53:32 -0300 Subject: [PATCH] Cli parsing now emits commands --- .rustfmt.toml | 3 +- Cargo.lock | 86 +++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + src/args.rs | 41 +++++++++++++----- src/commands/add_expense.rs | 36 +++++++++++++++- src/commands/mod.rs | 4 +- src/main.rs | 1 + 7 files changed, 158 insertions(+), 15 deletions(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index 5c8d931..422e03e 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1 +1,2 @@ -max_width = 80 \ No newline at end of file +max_width = 80 +edition = "2018" diff --git a/Cargo.lock b/Cargo.lock index f1d2a8e..dbac6f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,14 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -38,6 +47,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "chrono" version = "0.4.19" @@ -66,12 +81,27 @@ dependencies = [ "vec_map", ] +[[package]] +name = "env_logger" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "fernico" version = "0.1.0" dependencies = [ "chrono", "clap", + "env_logger", + "log", "rust_decimal", ] @@ -84,12 +114,33 @@ dependencies = [ "libc", ] +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "libc" version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + [[package]] name = "num-integer" version = "0.1.44" @@ -109,6 +160,23 @@ dependencies = [ "autocfg", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "rust_decimal" version = "1.13.0" @@ -132,6 +200,15 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -186,6 +263,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 8b2490a..a3903b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,5 @@ edition = "2018" clap = "2.33" rust_decimal = "1.13" chrono = "0.4" +env_logger = "0.8" +log = "0.4" diff --git a/src/args.rs b/src/args.rs index de5f1cb..de0b6c7 100644 --- a/src/args.rs +++ b/src/args.rs @@ -24,8 +24,20 @@ use clap::App; use clap::Arg; use clap::ArgMatches; use clap::SubCommand; +use rust_decimal::prelude::*; -pub(crate) fn cli() { +use crate::commands::add_expense::AddExpense; +use crate::commands::interface::Command; + +/// Errors in the CLI parsing +pub enum CliErrors { + /// Request to set a value without a value + ValueIsRequired, + /// There is no such command + NoSuchCommand, +} + +pub(crate) fn cli() -> Result, CliErrors> { let interface = App::new(crate_name!()) .version(crate_version!()) .author(crate_authors!()) @@ -50,22 +62,31 @@ pub(crate) fn cli() { ("expense", Some(expense_arguments)) => { parse_expenses(expense_arguments) } - _ => {} + _ => Err(CliErrors::NoSuchCommand), } } -fn parse_expenses(args: &ArgMatches) { - println!("{:?}", args); +fn parse_expenses(args: &ArgMatches) -> Result, CliErrors> { match args.subcommand() { ("add", Some(params)) => { - let value = params.value_of("value").unwrap(); // ok_or(Errors) - let tags = params.values_of("tags").unwrap(); - let date = params.value_of("date").ok_or("Today"); - println!( + let value = + params.value_of("value").ok_or(CliErrors::ValueIsRequired)?; + let tags = params.values_of("tags").map_or_else( + || vec![], /* else */ + |values| values.map(|val| val.into()).collect(), /* map */ + ); + let date = params.value_of("date").unwrap_or("Today"); + log::debug!( "Add expense on {:?}, of {:?}, with tags {:?}", - date, value, tags + date, + value, + tags ); + Ok(Box::new(AddExpense::new( + Decimal::from_str(value).unwrap(), + tags, + ))) } - _ => {} + _ => Err(CliErrors::NoSuchCommand), } } diff --git a/src/commands/add_expense.rs b/src/commands/add_expense.rs index e21a82c..87d9b1b 100644 --- a/src/commands/add_expense.rs +++ b/src/commands/add_expense.rs @@ -1,10 +1,42 @@ +/* + Fernico - Finance Storage + Copyright (C) 2021 Julio Biason + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + use crate::commands::interface::Command; -use chrono::DateTime; +use chrono::Date; use chrono::Utc; use rust_decimal::prelude::*; pub struct AddExpense { value: Decimal, tags: Vec, - date: DateTime, + date: Date, +} + +impl AddExpense { + pub fn new(value: Decimal, tags: Vec) -> Self { + Self { + value, + tags, + date: Utc::today(), + } + } +} + +impl Command for AddExpense { + fn execute(&self) {} } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 3ac64f3..bae28a2 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -15,5 +15,5 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ -mod add_expense; -mod interface; +pub mod add_expense; +pub mod interface; diff --git a/src/main.rs b/src/main.rs index b340a89..fe3dbc2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,5 +20,6 @@ mod args; mod commands; fn main() { + env_logger::init(); args::cli(); }