Skip to content

Commit

Permalink
complete oop style api up to what Book has to offer
Browse files Browse the repository at this point in the history
Came accross the lifetime issue again when `Book::running_balance` returns
`Transaction<'a>` where `'a` is of the book. This too does not cross the
`std::cell::Ref<'_, T>` boundry. However, there is a way to get to the underlying
lifetime through an unstable feature 'cell_leak'

see rust-lang/rust#69099

This allows the borrow checker to life-check!
  • Loading branch information
gomain committed Nov 17, 2020
1 parent fc807fe commit 3afcb25
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 15 deletions.
7 changes: 1 addition & 6 deletions src/accounting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,7 @@ pub struct Transaction<'a> {
}

impl<'a> Transaction<'a> {
pub fn new(
datetime: DateTime<Utc>,
from: &'a Account,
to: &'a Account,
money: Money,
) -> Self {
pub fn new(datetime: DateTime<Utc>, from: &'a Account, to: &'a Account, money: Money) -> Self {
Transaction {
datetime,
from,
Expand Down
49 changes: 43 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#![feature(cell_leak)]
pub mod accounting;
pub mod book;
pub mod monetary;

use accounting::*;
use std::cell::Ref;
use std::cell::RefCell;
use std::rc::Rc;

Expand All @@ -15,7 +17,9 @@ pub struct BookHandle<'a> {

impl<'a> BookHandle<'a> {
pub fn new() -> Self {
Self { book: Rc::new(RefCell::new(Book::new())) }
Self {
book: Rc::new(RefCell::new(Book::new())),
}
}

pub fn new_account(&'a self, name: &'a str) -> AccountHandle<'a> {
Expand All @@ -27,7 +31,7 @@ impl<'a> BookHandle<'a> {
.borrow()
.accounts()
.into_iter()
.map(|account| AccountHandle::new(account,self.book.clone()))
.map(|account| AccountHandle::new(account, self.book.clone()))
.collect()
}
}
Expand All @@ -39,24 +43,53 @@ pub struct AccountHandle<'a> {
}

impl<'a> AccountHandle<'a> {
fn new(account: Rc<Account>, book: Rc<RefCell<Book<'a>>>) -> Self /* AcconutHandle<'a> */ {
AccountHandle { account, book }
fn new(account: Rc<Account>, book: Rc<RefCell<Book<'a>>>) -> Self {
Self { account, book }
}

pub fn transfer(
pub fn transfer(&'a self, to: &'a AccountHandle<'a>, money: Money) -> TransactionHandle<'a> {
TransactionHandle::new(
self.book
.borrow_mut()
.transfer(&self.account, &to.account, money),
self.book.clone(),
)
}

pub fn transfer_at(
&'a self,
datetime: DateTime<Utc>,
to: &'a AccountHandle<'a>,
money: Money,
) -> TransactionHandle<'a> {
TransactionHandle::new(
self.book.borrow_mut().transfer(&self.account, &to.account, money),
self.book
.borrow_mut()
.transfer_at(datetime, &self.account, &to.account, money),
self.book.clone(),
)
}

pub fn balance(&self) -> Money {
self.book.borrow().balance(&self.account)
}

pub fn balance_at(&self, datetime: DateTime<Utc>) -> Money {
self.book.borrow().balance_at(datetime, &self.account)
}

pub fn running_balance(&'a self) -> Vec<(TransactionHandle<'a>, Money)> {
Ref::leak(self.book.borrow())
.running_balance(&self.account)
.into_iter()
.map(|(transaction, money)| {
(
TransactionHandle::new(transaction, self.book.clone()),
money,
)
})
.collect()
}
}

pub struct TransactionHandle<'a> {
Expand All @@ -68,4 +101,8 @@ impl<'a> TransactionHandle<'a> {
fn new(transaction: Rc<Transaction<'a>>, book: Rc<RefCell<Book<'a>>>) -> Self {
Self { transaction, book }
}

pub fn datetime(&self) -> DateTime<Utc> {
self.transaction.datetime()
}
}
4 changes: 1 addition & 3 deletions tests/book_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn transfer_between_two_accounts() {
assert_eq!(bank.balance().get(&thb).unwrap(), -40000);
assert_eq!(wallet.balance().get(&thb).unwrap(), 40000);
}
/*

#[test]
fn balance_at_dates() {
let mut book = BookHandle::new();
Expand Down Expand Up @@ -91,5 +91,3 @@ fn running_balance() {
vec![2000, 1600, 1300, 1100, 900, 800]
);
}
*/

0 comments on commit 3afcb25

Please sign in to comment.