Skip to content

bryceac/qif_rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Table of Contents

QIF

Version
0.1
Author
Bryce Campbell
License
see LICENSE
Description

A rust port of my Swift Library that can read and write QIF files

Notes

This crate was created with the aim of bringing QIF support to the CLI version of BCheckbook.

It has been tested on Rust 1.84.1 on macOS 15.3, though it should work on other platforms just fine.

Version History

0.1
initial release.

Limits

Like the original library I wrote in Swift, this was designed with only noninvestment and noninvoice data in mind.

While implementing them may seem trivial, there are potential conflicts as the QIF prefixes, as found on Wikipedia.

Also, the check number field is assumed to always be numerical.

Even though, there can be other values present in QIF values. This decision was made to keep things simplistic, since the Rust project I plan to use this with only allows numerical input.

Questions

  1. Why create this when there is already a parsing crate for rust?

    When I went looking for ways of reading QIF files, I did encounter qif_parser, which many people seem to like.

    However, I could not really use it if I wanted to generate a QIF file, which is what I wanted to do.

    Also, while I could have utilized it for the import functionality, trying to figure out how it worked and would mean I'd just be reimplementing things anyway.

    As such, it felt more worth it to just make it myself.

  2. Does this work the same as your original library, since this is a Rust port?

    While the design is the same, due to a focused need for only single entry components, there are some differences. For example, while my Swift library uses dictionaries, which Rust calls HashMaps, to store different types of QIF details, this port has those same sections as their own fields. This was done because making custom types hashable is not as easy to do in Rust.

    However, things should be just as simple.

  3. Are the QIF files produced here compatible with your iOS and macOS apps that use the original library?

    They should be compatible with the iOS apps when I get around to getting the library updated in the project.

    However, I am having troubles with the macOS app at this time, as there are updates that need to be pushed, but due to issues with third party libraries that would end up making the app unusable, I cannot push those updates out.

    Until the issues on the macOS side can be resolved, I suggest not using the QIF files generated by this library with the macOS GUI application.

Usage

To utilize this crate, add either of the following to Cargo.toml:

qif = "0.1"

Reading

To read a file, you would do something like this:

use qif::QIF;

fn main() {
let format = Date::DateFormat::MonthDayFullYear;

let qif = QIF::load_from_file("path/to/qif", &format);

if let Some(bank) = qif.bank {
    println!("{}", bank)
}
}

This will attempt to read a file and display details regarding bank transactions.

Writing to File

To write QIF data to a file, you would do something like this:

use qif::{ QIF, Section, Transaction };

fn main() {
...
let format = Date::DateFormat::MonthDayFullYear;
let bank_section = Section::builder()
        .set_type("Bank")
        .add_transaction(sam_hill)
        .add_transaction(fake_street)
        .add_transaction(velociraptor_entertainment)
        .build().unwrap();

let qif = QIF::builder()
        .set_field(bank_section)
        .build();

qif.save("path/to/qif", &format).unwrap();
}

This will take the bank transactions and save them to a QIF file.

Creating a Transaction

Transactions can be created like this:

use qif::Transaction;

fn main() {
let today = Local::now();

let format = DateFormat::MonthDayFullYear;

let transaction = Transaction::builder()
    .set_date(&today.format(format.chrono_str()).to_string(), &format)
    .set_check_number(1260)
    .set_vendor("Sam Hill Credit Union")
    .set_address("Sam Hill Credit Union")
    .set_category("Opening Balance")
    .set_amount(500.0)
    .set_memo("Open Account")
    .set_status("*")
    .build();
}

The date format above is optional, but it provides a convenience factor in that it houses some default schemes for chrono formats. The example provided above uses the MM/DD/YYYY format, and the status denotes it as reconciled.

Creating a Split

Splits can be created like this:

use qif::Split;

fn main() {
let split = Split::builder()
    .set_category("Opening Balance")
    .set_memo("Bonus for new Account")
    .set_amount(50.0)
    .build();
}

By substiting out set_amount for set_amount_via_percentage, you can have the calculations done for you, but you must also pass the original transaction's amount to the function.

Splits are then added to transactions like this:

use qif::{Split, Transaction };

fn main() {
    let transaction = Transaction::builder()
    .set_date(&today.format(format.chrono_str()).to_string(), &format)
    .set_check_number(1260)
    .set_vendor("Sam Hill Credit Union")
    .set_address("Sam Hill Credit Union")
    .set_category("Opening Balance")
    .set_amount(500.0)
    .set_memo("Open Account")
    .set_status("*")
    .add_split(split)
    .build();
}

Contributing

If you think you can help out making this even better, feel free to fork this project and make a pull request.

Please keep in mind that I may refuse the request, but if things work as they should, then I will likely accept it.

Support

While I have been writing more Rust code than Swift these days, I still do not think I can provide too much support, so you should expect to be on your own.

However, I am willing to check things out, so feel free to contact me at the email below:

[email protected]

About

Rust library to read and write QIF files

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages