-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
851 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
name: test | ||
on: | ||
push: | ||
branches: [ "main" ] | ||
pull_request: | ||
branches: [ "main" ] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: dtolnay/rust-toolchain@stable | ||
- run: cargo test --all-features |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
[package] | ||
name = "bean-rs" | ||
license = "MIT" | ||
authors = ["Chris Arderne <[email protected]"] | ||
description = "beancount clone in Rust" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
clap = { version = "4.4.18", features = ["derive"] } | ||
pest = "2.7.6" | ||
pest_derive = "2.7.6" | ||
|
||
[[bin]] | ||
name = "bean" | ||
path = "src/main.rs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.DEFAULT_GOAL = build | ||
|
||
.PHONY: build | ||
build: fmt | ||
cargo build | ||
|
||
.PHONY: release | ||
release: fmt | ||
cargo build --release | ||
|
||
.PHONY: run | ||
run: | ||
cargo run balance example.bean | ||
|
||
.PHONY: fmt | ||
fmt: | ||
cargo fmt | ||
|
||
.PHONY: test | ||
test: | ||
cargo test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,42 @@ | ||
# beaners | ||
beancount clone in Rust | ||
# bean-rs | ||
|
||
Basic [beancount](https://github.com/beancount/beancount) clone (one day...) in Rust! | ||
|
||
Using [pest](https://pest.rs/) for parsing. Two useful links: | ||
- [pest bootstrap parsing](https://github.com/pest-parser/pest/tree/master/meta/src) | ||
- [playground](https://pest.rs/#editor) | ||
|
||
Planned featuers: | ||
- [x] Parse beancount files | ||
- [x] Stricter transaction keywords | ||
- [x] Propagate line numbers for debugging | ||
- [ ] Calculate account balances | ||
- [ ] Use proper Decimal handling | ||
- [ ] Validate transactions against `open`/`close` directives | ||
- [ ] Validate `balance` directives | ||
- [ ] Open/close with multiple currencies | ||
|
||
## Usage | ||
### Install | ||
```bash | ||
cargo install bean-rs | ||
``` | ||
|
||
### Run | ||
``` | ||
$ bean | ||
Commands: | ||
balance | ||
help Print this message or the help of the given subcommand(s) | ||
Options: | ||
-h, --help Print help | ||
-V, --version Print version | ||
``` | ||
|
||
## Development | ||
### Build | ||
```bash | ||
make build | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
* Example beancount file | ||
|
||
** Random metadata stuff | ||
option "operating_currency" "GBP" | ||
2000-01-01 custom "fava-option" "language" "en" | ||
2000-01-01 commodity GBP | ||
name: "British Pound" | ||
|
||
** Open accounts | ||
2023-01-01 open Equity:Bals | ||
2023-01-01 open Assets:Bank GBP | ||
2023-01-02 open Assets:Invest GOO "FIFO" | ||
portfolio: "all" | ||
2023-01-03 open Expenses:Food GBP ;, USD | ||
2023-01-04 open Income:Job GBP | ||
|
||
** Transactions | ||
2023-02-01 * "Salary" ; comment | ||
user: "Chris" | ||
Assets:Bank 1000 GBP | ||
Income:Job | ||
|
||
2023-02-02 * "Buy food" | ||
Assets:Bank -100 GBP | ||
; comment | ||
Expenses:Food 100 GBP | ||
|
||
2023-02-05 * "Shop" "More food" #tag ^link | ||
Assets:Bank -40.00 GBP | ||
Expenses:Food 40.00 GBP | ||
|
||
** Balances and pads | ||
2023-03-01 pad Assets:Invest Equity:Bals | ||
2023-03-02 balance Assets:Invest 111 GOO | ||
2023-03-03 balance Assets:Bank 860 GBP | ||
|
||
** Close an account | ||
2023-12-01 close Assets:Bank | ||
|
||
** Prices | ||
2023-01-01 price GOOG 50 GBP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
root = { SOI ~ (NEWLINE* ~ entry ~ NEWLINE*)* ~ EOI } | ||
|
||
entry = _{ | ||
heading | ||
| option | ||
| custom | ||
| commodity | ||
| open | ||
| close | ||
| balance | ||
| pad | ||
| price | ||
| transaction | ||
| COMMENT | ||
| space+ | ||
} | ||
|
||
heading = _{ "*" ~ anyline } | ||
option = { "option" ~ (space+ ~ quoted){2} } | ||
custom = { date ~ space ~ "custom" ~ (space+ ~ quoted){3} } | ||
|
||
commodity = { date ~ space+ ~ "commodity" ~ space+ ~ ccy ~ metadata_added } | ||
open = { date ~ space+ ~ "open" ~ space+ ~ account ~ (space+ ~ ccy)? ~ (space+ ~ quoted)? ~ metadata_added* } | ||
close = { date ~ space+ ~ "close" ~ space+ ~ account } | ||
|
||
price = { date ~ space+ ~ "price" ~ space+ ~ ccy ~ space+ ~ amount } | ||
balance = { date ~ space+ ~ "balance" ~ space+ ~ account ~ space+ ~ amount } | ||
pad = { date ~ space+ ~ "pad" ~ space+ ~ account ~ space+ ~ account } | ||
|
||
transaction = { date ~ space+ ~ txn_type ~ space+ ~ payee ~ (space+ ~ narration)? ~ (space+ ~ tag)? ~ (space+ ~ link)? ~ (posting_added | metadata_added)* } | ||
payee = { quoted } | ||
narration = { quoted } | ||
posting_added = _{ (NEWLINE ~ posting) } | ||
posting = { space+ ~ account ~ (space+ ~ amount)? } | ||
|
||
metadata_added = _{ (NEWLINE ~ metadata) } | ||
metadata = { space+ ~ key ~ ":" ~ space* ~ val } | ||
|
||
txn_type = { "*" | "!" | "txn" } | ||
key = @{ ASCII_ALPHA_LOWER+ } | ||
val = @{ quoted } | ||
space = _{ " " | "\t" } | ||
quoted = _{ quote ~ inner_quoted ~ quote } | ||
inner_quoted = { (!quote ~ ANY)* } | ||
quote = _{ "\"" } | ||
|
||
date = @{ year ~ "-" ~ month ~ "-" ~ day } | ||
year = @{ '1'..'2' ~ ASCII_DIGIT ~ ASCII_DIGIT ~ ASCII_DIGIT } | ||
month = @{ '0'..'1' ~ ASCII_DIGIT } | ||
day = @{ '0'..'3' ~ ASCII_DIGIT } | ||
|
||
amount = { number ~ space+ ~ ccy } | ||
number = @{ "-"? ~ ASCII_DIGIT ~ (ASCII_DIGIT | ".")* } | ||
ccy = @{ ASCII_ALPHA_UPPER{3, 9} } | ||
|
||
account = @{ account_root ~ (":" ~ ASCII_ALPHA_UPPER ~ ASCII_ALPHA_LOWER+)+ } | ||
account_root = _{ "Assets" | "Liabilities" | "Income" | "Expenses" | "Equity" } | ||
|
||
tag = @{ "#" ~ ASCII_ALPHA_LOWER+ } | ||
link = @{ "^" ~ ASCII_ALPHA_LOWER+ } | ||
|
||
COMMENT = _{ NEWLINE? ~ space* ~ ";" ~ anyline } | ||
anyline = _{ (!NEWLINE ~ ANY)* } |
Oops, something went wrong.