# Traits: Rust's take on interfaces

We know structs represents complex data types. Rust's struct acts more like classes in Python and C++ once we implements struct using ```impl``` keyword and you have ```self``` to access structs attributes. However, struct doesn't support inheritance. So in that sense, you can say Rust is not an Object-oriented language. You can not define an abstract base struct and inherit to make a derived struct and probably another derived struct from derived one and make the code as unreadable and complex as possible for the developers like me. At least one good news about learning Rust is *Rust doesn't have inheritance*. 

That's great, however, the problem is, I learned design patterns a week ago from the awesome book [*Head First Design patterns*.](https://read.amazon.com/kp/embed?asin=B08P3X99QP&preview=newtab&linkCode=kpe&ref_=cm_sw_r_kb_dp_7EC49TBTHQC88FVA0GZT)
These concepts seem pretty universal, but then how do we apply them in Rust?

The answer is **Trait objects** and **Generics.** 

Let's focus on *trait object* for this discussion.
# [What is Trait](https://doc.rust-lang.org/stable/book/ch10-02-traits.html) 
As defined in the book **The Rust Programming Language**, (you can find it at: https://doc.rust-lang.org/stable/book) 
>A trait tells the Rust compiler about functionality a particular type has and
can share with other types. We can use traits to define shared behavior in
an abstract way.

To achieve the polymorphism in Rust, you need a pointer (reference) that can hold any references of any type that have shared behavior. We will use the ```dyn``` keyword for this pointer.

Let's understand this with a simple example where we will create type of financial contracts and a trade that can refer to different types of financial contracts:

# Define a Trait
We have a variety of financial instruments from different asset classes like equity, equity options, and interest rate derivatives. We need a few generic methods on all of the contracts so that we can analyze the portfolio of trades.

We define a trait named ```Contract``` with one method named ```npv```.

```rust
pub trait Contract{
    fn npv(&self);
}
```
The above function may look like a virtual method in C++. 
# Define a Struct with a trade object
Let's create a struct named ```Trade```. The idea is to store our traded financial contracts. Here we use a trait object that allows different types of contracts.
```rust
pub struct Trade{
    contract: Box<dyn Contract>
}
```
dyn Contract is a trade object. ```Box<dyn Contract>``` is a fat pointer that consists of a pointer to the value, plus a pointer to a table representing a value type. This table is the same as a C++ virtual table (vtable). Our Trade type can hold the reference to any structs that implement the Contract trait.  

Refer: 
https://doc.rust-lang.org/book/ch17-02-trait-objects.html

# Define different types and implement Trait
Let's just create two instruments that can be widely different. We don't have to go into detail of swap and swaption for this example. We have ```Swap``` and ```Swaption```, both implementing ```Contract```.  
```rust
pub struct Swap;
impl Contract for Swap {
    fn npv(&self) {
        println!("This is npv of Swap")
    }
}
pub struct Swaption;
impl Contract for Swaption {
    fn npv(&self) {
        println!("This is npv of Swaption")
    }
} 
```
The syntex *impl TraitName for Type* is used to implement a trait. This *impl* block must have only the features of the trait. For other methods, you need to use different *impl* blocks.
# Implement Trade type
```rust
impl Trade {
    pub fn new() -> Self {
        Trade {
            contract: Box::new(Swap),
        }
    }
    pub fn npv(&self) {
        self.contract.npv();
    }
    pub fn set_contract(&mut self, contract: Box<dyn Contract>){
        self.contract = contract;
    }
}
```
We define a new method to create a Swap by default. Rust does not have constructors too, instead, the convention is to use an associated function ``` new``` to create an object: We have an additional set_contract method that takes the trait object and updates the contract. We also define the npv that calls the trait object's npv based on run-time polymorphism.

# Puting it all together
```rust
    let mut trade = Trade::new();
    trade.npv();
    println!("Setting new contract");
    trade.set_contract(Box::new(Swaption));
    trade.npv();
```
```rust
This is npv of Swap
Setting new contract
This is npv of Swaption

```

# Speaking of design patterns
We just used the strategy design pattern to calculate the npv of trades. Contract Traits makes different types (Swap and Swaption) interchangeable inside the Trade type. In the words of HFDP 
> The strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Thank you for reading this, and good luck with your Rust and design patterns!




