From 60cc74d344a97b368e7b31b37d3c29aa49fc1602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Thu, 29 Jul 2021 13:23:28 +0200 Subject: model -> transaction/store --- cli/src/transaction.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 cli/src/transaction.rs (limited to 'cli/src/transaction.rs') diff --git a/cli/src/transaction.rs b/cli/src/transaction.rs new file mode 100644 index 0000000..117edfb --- /dev/null +++ b/cli/src/transaction.rs @@ -0,0 +1,64 @@ +use chrono::naive::NaiveDate; +use rust_decimal::Decimal; +use serde::{Deserialize, Serialize}; +use std::convert::AsRef; +use std::fs; +use std::hash::{Hash, Hasher}; +use std::path::Path; +use structopt::StructOpt; +use twox_hash::XxHash64; + +pub(crate) type Account = String; +pub(crate) type Category = String; + +#[derive(Debug)] +#[derive(Hash)] +#[derive(Deserialize, Serialize)] +#[derive(StructOpt)] +pub enum TransactionKind { + Expense, + Income, + //TODO Transfer, +} + +impl std::str::FromStr for TransactionKind { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "expense" => Ok(TransactionKind::Expense), + "income" => Ok(TransactionKind::Income), + _ => Err(format!("Unknown transaction kind: {:?}", s)), + } + } +} + +#[derive(Debug)] +#[derive(Hash)] +#[derive(Deserialize, Serialize)] +pub struct Transaction { + pub description: String, + pub date: NaiveDate, + pub category: Category, + pub amount: Decimal, + pub kind: TransactionKind, + pub from: Account, + pub to: Account, +} + +impl Transaction { + pub(crate) fn write>(&self, p: &P) -> std::io::Result<()> { + fs::write(p, serde_json::to_string_pretty(self).unwrap()) //TODO control pretty or not + } + + //TODO Result + pub(crate) fn open>(p: &P) -> Option { + fs::read_to_string(p).ok().as_ref().and_then(|s| serde_json::from_str(s).ok()) + } + + pub fn id(&self) -> u64 { + let mut h = XxHash64::default(); + self.hash(&mut h); + h.finish() + } +} -- cgit v1.2.1