summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2017-11-23 22:03:02 +0200
committerJustin Worthe <justin@worthe-it.co.za>2017-11-23 22:03:02 +0200
commit817d06fc2ef4f8e258d906fad96c26f72b32c702 (patch)
tree5ba5266955d22a9d669a38c0fbb3d2f42c6f6ede
Basic functionality: parses qif files and strips T=0 entries
-rw-r--r--.gitignore2
-rw-r--r--Cargo.lock4
-rw-r--r--Cargo.toml6
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs25
-rw-r--r--src/qif.rs76
6 files changed, 114 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..eccd7b4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target/
+**/*.rs.bk
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..ad707a0
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,4 @@
+[root]
+name = "qif_parser"
+version = "0.1.0"
+
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..7c48e58
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "qif_parser"
+version = "0.1.0"
+authors = ["Justin Worthe <justin@worthe-it.co.za>"]
+
+[dependencies]
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..51368c5
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1 @@
+pub mod qif;
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..291c548
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,25 @@
+extern crate qif_parser;
+use qif_parser::qif::*;
+use std::io::*;
+
+
+fn main() {
+ let stdin = stdin();
+ let stdin_lock = stdin.lock();
+ let mut lines = stdin_lock.lines();
+
+ let mut file = QifFile::new(lines.next().unwrap().unwrap());
+ let mut next_entry = Vec::new();
+
+ for line_result in lines {
+ let line = line_result.unwrap();
+ if line == String::from("^") {
+ file.append_non_empty(QifEntry::new(&next_entry));
+ next_entry.clear();
+ } else {
+ next_entry.push(line);
+ }
+ }
+
+ println!("{}", file);
+}
diff --git a/src/qif.rs b/src/qif.rs
new file mode 100644
index 0000000..46b2bc3
--- /dev/null
+++ b/src/qif.rs
@@ -0,0 +1,76 @@
+use std::fmt;
+
+pub struct QifFile {
+ header: String,
+ entries: Vec<QifEntry>
+}
+
+impl QifFile {
+ pub fn new(header: String) -> QifFile {
+ QifFile {
+ header: header,
+ entries: Vec::new()
+ }
+ }
+
+ pub fn append_non_empty(&mut self, entry: QifEntry) {
+ if !entry.is_empty() {
+ self.entries.push(entry);
+ }
+ }
+
+ pub fn append(&mut self, entry: QifEntry) {
+ self.entries.push(entry);
+ }
+}
+
+impl fmt::Display for QifFile {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut hat_separated = String::new();
+
+ for entry in &self.entries {
+ hat_separated.push_str("\n");
+ hat_separated.push_str(&entry.to_string());
+ hat_separated.push_str("\n^");
+ }
+
+ write!(f, "{}{}", self.header, hat_separated)
+ }
+}
+
+pub struct QifEntry {
+ date: String,
+ amount: String,
+ description: String
+}
+
+const DATE_PREFIX: &str = "D";
+const AMOUNT_PREFIX: &str = "T";
+const DESCRIPTION_PREFIX: &str = "M";
+
+impl QifEntry {
+ pub fn new(lines: &Vec<String>) -> QifEntry {
+ let date = lines.iter().find(|l| l.starts_with(DATE_PREFIX)).expect("No date");
+ let amount = lines.iter().find(|l| l.starts_with(AMOUNT_PREFIX)).expect("No amount");
+ let description = lines.iter().find(|l| l.starts_with(DESCRIPTION_PREFIX)).expect("No description");
+ QifEntry {
+ date: date.clone(),
+ amount: amount.clone(),
+ description: description.clone()
+ }
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.amount == String::from("T0")
+ }
+
+ pub fn clean_description(&self) -> String {
+ self.description.clone()
+ }
+}
+
+impl fmt::Display for QifEntry {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}\n{}\n{}", self.date, self.amount, self.clean_description())
+ }
+}