9 releases (breaking)
|0.7.0||Sep 7, 2023|
|0.6.0||Jun 11, 2023|
|0.5.0||Jun 5, 2023|
|0.4.0||Jun 3, 2023|
|0.1.0||May 31, 2023|
#15 in Finance
56 downloads per month
Ledger-cli functionality implemented in Rust
A brand new attempt at Ledger, starting from blank slate.
[Early Work In Progress!]
This library is aiming to implement the plain-text accounting principles, as demonstrated by Ledger-cli, Hledger, Beancount, etc. The base for development is Ledger-cli, from which the underlying model and concepts were applied.
Part of the Rusty Ledger project.
While still early work-in-progress, the basic functionality is there. Simple Ledger journal files with transactions are being parsed. The basic functionality allows retrieving the parsed entities (Transactions, Posts, Accounts, Cost, Amounts), which allow the very basic reports to be provided.
The functionality will now be expanded. The direction will be tracked through work items (issues) in the repository.
Any kind of contribution is wellcome, from using the library and providing feedback, to participating in discussions and submitting pull-requests with implementations and improvements.
After a few attempts at rewriting (pieces of) Ledger, the following conclusions seemed to crystalize:
One package While trying to create just a parser, it became clear that there is no need to separate the parser from the rest of the application (model, reports). They can coexist in the same crate. The parser can still be used independently of other functionality. The model and the reports are easier to include in the same crate from the beginning. These can be separated if ever needed.
Clean Rust Trying to convert the C++ structure into Rust just doesn't make much sense. The pointer arithmetic in the original Ledger seems next to impossible to create and maintain in Rust. The references and lifetimes make development a nightmare in Rust. A clean start, applying idiomatic Rust concepts should apply.
Start minimal Ledger really contains a lot of features. Start from a minimal working version and expand from there.
Define clear goals Trying to rewrite the whole application seems a neverending task. Rather, define clear and small, attainable goals and implement them.
The goals beyond the initial requirements, which served as a proof-of-concept, will be tracked as issues in the source repository.
Initial functional requirements
The immediate goals are:
- Parse a minimal working transaction sample
- Create a minimal working reports:
- Compile a working WASM version
- that works in console
These should provide initial insights into Ledger's inner workings and concepts.
- Fast execution
- Test coverage
- Permanent storage (sqlite?) as a base for the reporting layer
To compile to Wasm for execution in WASI, run
cargo build --target wasm32-wasi
then go to the
target/wasm32-wasi/debug folder and run
wasmer run --dir tests target/wasm32-wasi/debug/ledger-rs-lib.wasm -- -f tests/minimal.ledger
This will run the CLI's main() method. With WASI, the filesystem access permission has to be given explicitly. This is done with
Note that Wasmer is using
-- to separate application switches like
You need to have the prerequisites install - the compilation target (wasm32-wasi) and a Wasm runtime (i.e. wasmer).
The library can be compiled into WASM for use in web apps.
cargo install wasm-pack wasm-pack build --target web
wwwroot contains the code that uses the wasm.
Serve with a web server. I.e. using Deno's file server:
deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts file_server wwwroot
Add the deno plugin location to path.
I will try to document the Ledger's Journal format in a syntax diagram. This is the Extended Backus–Naur Form (EBNF) diagram source.
The original specs from Ledger's documentation:
DATE[=EDATE] [*|!] [(CODE)] DESC
ACCOUNT AMOUNT [; NOTE]
P DATE SYMBOL PRICE
The price of a commodity is stored in commodity annotations (
annotate_commodity(amount_t price, [datetime_t date, string tag])