Skip to content

Accounts and Bank Implementation

Daniel Cortes edited this page Nov 4, 2024 · 1 revision
Screenshot 2024-11-03 at 10 14 52 PM

So the last method we are going to add to Account, I want to have a function that creates an account summary as a string and returns it.

So essentially a function that is going to take the account holder and just join them together in a string. This will be a method called summary() and return it. It will probably return a string.

Inside my impl Account I will add in a new method called summary:

impl Account {
    fn new(id: u32, holder: String) -> Self {
        Account {
            id,
            holder,
            balance: 0,
        }
    }

    fn summary(&self) -> String {
        format!("{} has a balance {}", self.holder, self.balance);
    }

Let's test this out:

➜  bank git:(master) ✗ cargo run -q
warning: field `id` is never read
 --> src/main.rs:3:5
  |
2 | struct Account {
  |        ------- field in this struct
3 |     id: u32,
  |     ^^
  |
  = note: `Account` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
  = note: `#[warn(dead_code)]` on by default

me has a balance 250
Bank {
    accounts: [
        Account {
            id: 1,
            balance: 250,
            holder: "me",
        },
    ],
}

Right above the print statement for the bank we see bank holder which is me has a balance of 250.

Screenshot 2024-11-03 at 10 24 59 PM

Now we want to have another method where we calculate and return the total balance of all accounts. I think we can call it something like total_balance() it will not need any arguments and it will probably return an i32.

#[derive(Debug)]
struct Bank {
    accounts: Vec<Account>,
}

impl Bank {
    fn new() -> Self {
        Bank { accounts: vec![] }
    }

    fn add_account(&mut self, account: Account) {
        self.accounts.push(account);
    }

    fn total_balance(&self) -> i32 {
        self.accounts.iter().map(|account| account.balance).sum()
    }
}
Screenshot 2024-11-03 at 10 32 04 PM

Now we need to create a vector containing the summary of all accounts called summary() no args required and it will return a Vec<String>.

To implement this we will add another method to our impl Bank:

#[derive(Debug)]
struct Bank {
    accounts: Vec<Account>,
}

impl Bank {
    fn new() -> Self {
        Bank { accounts: vec![] }
    }

    fn add_account(&mut self, account: Account) {
        self.accounts.push(account);
    }

    fn total_balance(&self) -> i32 {
        self.accounts.iter().map(|account| account.balance).sum()
    }

    fn summary(&self) -> Vec<String> {
        self.accounts
            .iter()
            .map(|account| account.summary())
            .collect::<Vec<String>>()
    }
}

So now I need to print out a total balance of all accounts and a summary of all accounts as well. To test this out down inside of fn main() I will do the following:

fn main() {
    // do not forget to make bank variable mutable
    let mut bank = Bank::new();
    let mut account = Account::new(1, String::from("me"));

    account.deposit(500);
    account.withdraw(250);

    bank.add_account(account);

    println!("{:#?}", bank.summary());
    println!("{}", bank.total_balance());
}

Quick test now:

  = note: `Account` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
  = note: `#[warn(dead_code)]` on by default

[
    "me has a balance 250",
]
250

I have printed out my collection of summary here and the total balance of all accounts.

We have a big set of rules on ownership and borrowing and lifetimes as well here.