Algebraic type system in rust is great
Rust has a powerful algebraic type system, it is easy to construct rich domains. Here is a simplistic example of a card payment domain.
This feature is really similar to F# which I really liked.
#![allow(unused)]
type CheckNumber = u32;
type CardNumber = String;
enum CardType {
Visa,
Mastercard,
}
#[derive(Debug)]
struct CreditInfo(CheckNumber, CardNumber);
#[derive(Debug)]
enum PaymentMethod {
Cash,
Check(CheckNumber),
Card(CreditInfo),
}
type PaymentAmount = f32;
#[derive(Debug)]
enum Currency {
Eur,
Usd,
}
#[derive(Debug)]
struct Payment {
amount: PaymentAmount,
currency: Currency,
method: PaymentMethod,
}
trait PrintDetails {
fn payment_info(&self) -> String;
}
impl PrintDetails for Payment {
fn payment_info(&self) -> String {
let method = match &self.method {
PaymentMethod::Cash => String::from("cash"),
PaymentMethod::Check(c) => format!("a check with number {:?}", c),
PaymentMethod::Card(c) => format!("a check {} with a credit card {}", c.0, c.1),
};
format!(
"An amount of {}, was paid in {:?}, using {}",
&self.amount, &self.currency, method
)
}
}
fn main() {
let cc_payment = Payment {
amount: 100.33,
currency: Currency::Usd,
method: PaymentMethod::Card(CreditInfo(122, String::from("452389798712097"))),
};
let check_payment = Payment {
amount: 0.33,
currency: Currency::Eur,
method: PaymentMethod::Check(42),
};
println!("Payment details \
{}", check_payment.payment_info());
println!("Payment details \
{}", cc_payment.payment_info());
}
Results:
Payment details
An amount of 0.33, was paid in Eur, using a check with number 42
Payment details
An amount of 100.33, was paid in Usd, using a check 122 with a credit card 452389798712097