Browse Source

Add an event

master
Julio Biason 4 years ago
commit
c9f713390c
  1. 4
      .gitignore
  2. 231
      Cargo.lock
  3. 13
      Cargo.toml
  4. 75
      src/args/mod.rs
  5. 19
      src/args/validators.rs
  6. 47
      src/eventlist/event.rs
  7. 42
      src/eventlist/eventlist.rs
  8. 2
      src/eventlist/mod.rs
  9. 26
      src/main.rs

4
.gitignore vendored

@ -0,0 +1,4 @@
/target
events.toml
.idea
*.sw?

231
Cargo.lock generated

@ -0,0 +1,231 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "chrono"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
dependencies = [
"num-integer",
"num-traits",
"time",
]
[[package]]
name = "clap"
version = "2.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "hermit-abi"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
dependencies = [
"libc",
]
[[package]]
name = "libc"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "num-integer"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
[[package]]
name = "serde"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
[[package]]
name = "serde_derive"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "time"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
dependencies = [
"libc",
"redox_syscall",
"winapi",
]
[[package]]
name = "toml"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
dependencies = [
"serde",
]
[[package]]
name = "tu"
version = "0.1.0"
dependencies = [
"chrono",
"clap",
"serde",
"serde_derive",
"toml",
]
[[package]]
name = "unicode-width"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

13
Cargo.toml

@ -0,0 +1,13 @@
[package]
name = "tu"
description = "TimeUP!"
version = "0.1.0"
authors = ["Julio Biason <julio.biason@gmail.com>"]
edition = "2018"
[dependencies]
chrono = "0.4.11"
clap = "2.33.0"
serde = "*"
serde_derive = "*"
toml = "0.5"

75
src/args/mod.rs

@ -0,0 +1,75 @@
use clap::crate_authors;
use clap::crate_description;
use clap::crate_name;
use clap::crate_version;
use clap::App;
use clap::Arg;
use clap::ArgMatches;
use clap::SubCommand;
mod validators;
type Description = String;
type Date = String;
type Time = String;
#[derive(Debug)]
pub enum Action {
List,
Add(Description, Date),
AddWithTime(Description, Date, Time),
}
pub fn parse() -> Result<Action, ()> {
let params = App::new(crate_name!())
.version(crate_version!())
.author(crate_authors!())
.about(crate_description!())
.subcommand(
SubCommand::with_name("add")
.about("Add a new event")
.arg(
Arg::with_name("date")
.required(true)
.takes_value(true)
.validator(validators::date)
.help("Date for the event, in YYYY-MM-DD format"),
)
.arg(
Arg::with_name("description")
.required(true)
.takes_value(true)
.help("Event description"),
)
.arg(
Arg::with_name("time")
.short("t")
.long("time")
.takes_value(true)
.required(false)
.validator(validators::time)
.help("Time for the event"),
),
);
let matches = params.get_matches();
match matches.subcommand() {
("", _) => Ok(Action::List),
("add", Some(arguments)) => parse_add(arguments),
(_, _) => Err(()),
}
}
fn parse_add(arguments: &ArgMatches) -> Result<Action, ()> {
let description = arguments.value_of("description").unwrap();
let date = arguments.value_of("date").unwrap();
if let Some(time) = arguments.value_of("time") {
Ok(Action::AddWithTime(
description.into(),
date.into(),
time.into(),
))
} else {
Ok(Action::Add(description.into(), date.into()))
}
}

19
src/args/validators.rs

@ -0,0 +1,19 @@
use chrono::prelude::*;
pub fn date(input: String) -> Result<(), String> {
let fake_datetime = format!("{} 00:00:00", input);
if let Ok(_) = dbg!(Utc.datetime_from_str(&fake_datetime, "%Y-%m-%d %H:%M:%S")) {
Ok(())
} else {
Err(format!("Invalid date: '{}'", input))
}
}
pub fn time(input: String) -> Result<(), String> {
let fake_datetime = format!("2020-01-01 {}:00", input);
if let Ok(_) = dbg!(Utc.datetime_from_str(&fake_datetime, "%Y-%m-%d %H:%M:%S")) {
Ok(())
} else {
Err(format!("Invalid time: '{}'", input))
}
}

47
src/eventlist/event.rs

@ -0,0 +1,47 @@
use chrono::prelude::*;
use serde_derive::Deserialize;
use serde_derive::Serialize;
#[derive(Serialize, Deserialize, Debug)]
pub struct Date {
year: i32,
month: u32,
day: u32,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Time {
hour: u32,
min: u32,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "due", content = "datetime")]
pub enum EventDateType {
AllDay(Date),
AtTime(Date, Time),
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Event {
description: String,
due: EventDateType,
}
impl Event {
pub fn new_on_date(description: &str, date: &str) -> Self {
let fake_datetime = format!("{} 00:00:00", date);
if let Ok(dt) = Utc.datetime_from_str(&fake_datetime, "%Y-%m-%d %H:%M:%S") {
Self {
description: description.into(),
due: EventDateType::AllDay(Date {
year: dt.year(),
month: dt.month(),
day: dt.day(),
}),
}
} else {
panic!("Failed to parse the date");
}
}
}

42
src/eventlist/eventlist.rs

@ -0,0 +1,42 @@
use serde_derive::Deserialize;
use serde_derive::Serialize;
use std::fs::File;
use std::io::{Read, Write};
use toml;
use crate::eventlist::event::Event;
static FILENAME: &str = "events.toml";
#[derive(Serialize, Deserialize, Debug)]
pub struct EventList {
events: Vec<Event>,
}
impl EventList {
fn empty() -> Self {
Self { events: Vec::new() }
}
pub fn load() -> Self {
if let Ok(mut fp) = File::open(FILENAME) {
let mut content = String::new();
fp.read_to_string(&mut content)
.expect("Your event file is corrupted");
toml::from_str(&content).unwrap_or(EventList::empty())
} else {
EventList::empty()
}
}
pub fn push(&mut self, event: Event) {
self.events.push(event);
}
pub fn save(&self) {
let content = toml::to_string(&self).unwrap();
if let Ok(mut fp) = File::create(FILENAME) {
fp.write_all(content.as_bytes()).unwrap();
}
}
}

2
src/eventlist/mod.rs

@ -0,0 +1,2 @@
pub mod event;
pub mod eventlist;

26
src/main.rs

@ -0,0 +1,26 @@
mod args;
mod eventlist;
use crate::eventlist::event::Event;
use crate::eventlist::eventlist::EventList;
fn main() {
if let Ok(command) = dbg!(args::parse()) {
match command {
args::Action::List => list(),
args::Action::Add(description, date) => add_with_date(&description, &date),
_ => println!("Unknown command"),
}
}
}
fn list() {
unimplemented!()
}
fn add_with_date(description: &str, date: &str) {
let event = Event::new_on_date(description, date);
let mut event_list = dbg!(EventList::load());
event_list.push(event);
event_list.save();
}
Loading…
Cancel
Save