3 releases
0.1.3 | Jun 25, 2024 |
---|---|
0.1.2 | Jun 25, 2024 |
0.1.0 | Jun 25, 2024 |
#65 in Simulation
44KB
862 lines
Project Overview
This project is a banking system simulation written in Rust. It includes entities such as Wallets and Accounts, and uses traits, generics, and polymorphism to provide a flexible and extensible design.
Entities
Wallet
A Wallet can hold multiple accounts. It has a unique wallet_id
and a wallet_type
which can be either Basic
or MultiCurrency
.
Account
An Account represents a bank account with a specific currency.
It has a unique account_number
and an account_type
which can be either Basic
or Premium
.
BasicWallet
and MultiCurrencyWallet
are two different implementations of the Wallet
trait,
each with its own unique characteristics.
BasicWallet
BasicWallet
is a simple wallet that can hold only one account.
It uses generics to allow for different types of accounts to be added to the wallet.
The account is set during the creation of the BasicWallet
, and it cannot be changed afterward.
This design is suitable for scenarios where a wallet is expected to have only one account.
MultiCurrencyWallet
MultiCurrencyWallet
, on the other hand, can hold multiple accounts, each with a different currency.
Unlike BasicWallet
, it does not use generics. Instead, it uses a vector to store multiple boxed Account
trait objects.
This allows for different types of accounts to be added to the wallet after its creation.
This design is suitable for scenarios where a wallet is expected to handle multiple currencies.
The use of generics in BasicWallet
and not in MultiCurrencyWallet
is due to their different requirements.
BasicWallet
needs to know the exact type of its account at compile time, hence the use of generics.
MultiCurrencyWallet
needs to handle multiple accounts of potentially different types, hence the use of trait objects.
Traits, Generics, and Polymorphism
Traits
Traits are used to define shared behavior. In this project, the Wallet
and Account
traits define a common
interface for all types of wallets and accounts.
Traits in Rust:
- Traits are used to define shared behavior.
- A trait is defined with the trait keyword, followed by the trait's name.
- Traits can have methods with or without default implementations.
- Traits can be implemented for any data type.
- Traits can be used as function parameters, enabling dynamic dispatch.
- Traits can be used as trait bounds on generic parameters, enabling static dispatch.
- Traits can inherit from other traits. This is done by specifying the parent trait in the trait definition.
- The child trait will then include the method signatures of the parent trait.
Generics
Generics are used in the Wallet
trait to allow for different types of accounts to be added to a wallet.
The BasicWallet
struct is generic over the Account
type, which allows it to hold any type that implements the Account
trait.
The MultiCurrencyWallet
struct, on the other hand, uses trait objects to store multiple accounts of different types.
Generics in Rust:
- Generics are used to create functions and data types that can work with multiple types of data.
- Generics are declared using angle brackets where T is a placeholder for the type.
- The actual type for T is determined at compile time.
- Generics can be constrained by traits to only accept types that implement certain behaviors.
- Multiple generic types can be used by separating them with commas, like <T, U>.
- Lifetimes, which dictate how references to data should be handled, can also be generic.
Polymorphism
Polymorphism is used to allow for different types of wallets and accounts to be treated the same way.
For example, a BasicWallet
and a MultiCurrencyWallet
can both be treated as a Wallet
.
a BasicAccount
and a PremiumAccount
can both be treated as an Account
.
Polymorphism in Rust:
- Rust achieves polymorphism through the use of traits and trait objects.
- A trait defines a set of methods that a type must have to be considered as implementing that trait.
- Trait objects allow for multiple different types, each of which implement a particular trait, to be treated as the same general type.
- Trait objects are created by specifying a trait behind a reference, box, or other pointer type, like &dyn Trait or Box.
- Trait objects are dynamic and their type is checked at runtime.
Functions
Wallet Functions
add_account
: Adds an account to the wallet.balance
: Returns the balance of the wallet for a specific currency.get_wallet_id
: Returns the unique ID of the wallet.get_wallet_type
: Returns the type of the wallet.find_account_index_by_currency
: Finds the index of an account in the wallet by currency.get_account_number_by_index
: Returns the account number of an account at a specific index in the wallet.get_account_by_currency
: Returns an account in the wallet by currency.transfer
: Transfers money from the wallet to another wallet.deposit
: Deposits money into the wallet.withdraw
: Withdraws money from the wallet.
Account Functions
get_account_number
: Returns the unique account number.get_account_type
: Returns the type of the account.get_balance
: Returns the balance of the account.get_currency
: Returns the currency of the account.deposit
: Deposits money into the account.withdraw
: Withdraws money from the account.transfer
: Transfers money from the account to another account.
Enums
WalletType
This enum represents the type of wallet. It can be either Basic
or MultiCurrency
.
AccountType
This enum represents the type of account. It can be either Basic
or Premium
.
ID Generation
The wallet_id
and account_number
are unique identifiers for wallets and accounts respectively.
Building and Testing
To build the project, navigate to the project directory and run the following command:
cargo build
To run the tests, use the following command:
cargo test
Please ensure that you have Rust and Cargo installed on your system before building or testing the project.
Dependencies
~2.5MB
~40K SLoC