1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Implementations of standard operators:  `Add`, `Sub`, `Mul`, `Div`

use std::ops::{Add, Sub, Mul, Div};
use ::Currency;

/// Overloads the '+' operator for Currency objects.
///
/// # Panics
/// Panics if the two addends are different types of currency, as denoted by the Currency's symbol.
impl Add for Currency {
    type Output = Currency;

    #[inline]
    fn add(self, rhs: Currency) -> Currency {
        if self.symbol == rhs.symbol || self.symbol.is_none() {
            Currency{symbol: rhs.symbol, value: self.value + rhs.value}
        } else {
            panic!("Cannot add two different types of currency!\n{:?} vs {:?}",
                   self.symbol,
                   rhs.symbol);
        }
    }
}

/// Overloads the '-' operator for Currency objects.
///
/// # Panics
/// Panics if the minuend and subtrahend are two different types of currency, as denoted by the
/// Currency's symbol.
impl Sub for Currency {
    type Output = Currency;

    #[inline]
    fn sub(self, rhs: Currency) -> Currency {
        if self.symbol == rhs.symbol {
            Currency{symbol: self.symbol, value: self.value - rhs.value}
        } else {
            panic!("Cannot subtract two different types of currency!");
        }
    }
}

/// Overloads the '*' operator for Currency objects.
///
/// Allows a Currency to be multiplied by an i64.
impl Mul<i64> for Currency {
    type Output = Currency;

    #[inline]
    fn mul(self, rhs: i64) -> Currency {
        Currency{symbol: self.symbol, value: self.value * rhs}
    }
}

/// Overloads the '*' operator for i64.
///
/// Allows an i64 to be multiplied by a Currency.
/// Completes the commutative property for i64 multiplied by Currency.
impl Mul<Currency> for i64 {
    type Output = Currency;

    #[inline]
    fn mul(self, rhs: Currency) -> Currency {
        Currency{symbol: rhs.symbol, value: rhs.value * self}
    }
}

/// Multiplies with float, probably not a good idea, help appreciated.
impl Mul<f64> for Currency {
    type Output = Currency;

    #[inline]
    fn mul(self, rhs: f64) -> Currency {
        Currency{symbol: self.symbol, value: (self.value as f64 * rhs).round() as i64}
    }
}

impl Mul<Currency> for f64 {
    type Output = Currency;

    #[inline]
    fn mul(self, rhs: Currency) -> Currency {
        rhs * self
    }
}

/// Overloads the '/' operator for Currency objects.
///
/// Allows a Currency to be divided by an i64.
impl Div<i64> for Currency {
    type Output = Currency;

    #[inline]
    fn div(self, rhs: i64) -> Currency {
        Currency{symbol: self.symbol, value: self.value / rhs}
    }
}