Now do you see?

trust me, you don't. Lets make this even better. This small change makes a lot of things possible. Watch this, i can impl Area on any type, even types I don't own, like a f64.





















Complete Code

woah...

impl Area for f64 {
    fn area(&self) -> f64 {
        return self * self;
    }
}

fn main() {
    println!("area: {}", 6.9.area());
}

WAIT, THIS IS DANGEROUS, THESE ARE POLYFILLS!!! GLOBAL STATE CHANGE IS BAD!!!





















It gets even better

Let's move Area trait and trait implementations into shapes.rs

use std::f64::consts::PI;

pub struct Rectangle {
    pub x: f64,
    pub y: f64,
    pub width: f64,
    pub height: f64,
}

pub struct Circle {
    pub x: f64,
    pub y: f64,
    pub radius: f64,
}

pub trait Area {
    fn area(&self) -> f64;
}

impl Area for Rectangle {
    fn area(&self) -> f64 {
        return self.width * self.height;
    }
}

impl Area for Circle {
    fn area(&self) -> f64 {
        return self.radius * self.radius * PI
    }
}

impl Area for f64 {
    fn area(&self) -> f64 {
        return self * self;
    }
}




















Lets go back to our main file and just type this.

fn main() {
    println!("area: {}", 6.9.area());
}

Why does this error? Didn't we implement Area for f64





















BIG TAKE AWAY 1.

Traits must be imported to work

This means there is no global polyfills... In JavaScript you edit the prototype and now you have this function, but it exists for the whole project

In Rust, its only for files that import the trait

> Number.prototype.area = function() { return this * this; }
[Function (anonymous)]

> (5).area()
25




















Tell me that is not cool.

(we are not done yet...)

i must fail to succeed





















Lets organize our files a bit more

Lets create the following structure in our code base, and then move the contents of shapes.rs into shapes/mod.rs

mod.rs is effectively the same thing as index.ts

TypeScript

src/
  shapes/
    index.ts
  index.ts

Rust

src/
  shapes/
    mod.rs
  main.rs




















Lets further break up the rust files

Move each related code to each file

src/
  shapes/
    mod.rs
    rect.rs
    circle.rs
    area.rs
  main.rs

mod.rs

pub mod rect;
pub mod circle;
pub mod area;




















Lets create a Rectangle!

To prove we have everything working, lets create a Rectangle in our main file.





















This is annoying to type

mod shapes;

use shapes::rect::Rectangle;

fn main() {
    let rect = Rectangle {
        height: 10.0,
        width: 10.0,
        x: 0.0,
        y: 0.0,
    };
}




















Lets implement the default method

This also allows us to have some amazing other integrations, but for now its nice to just have a way to create the default rectangle and circle.

(to the code)





















Complete Code

src/shapes/rect.rs

use super::area::Area;

pub struct Rectangle {
    pub x: f64,
    pub y: f64,
    pub width: f64,
    pub height: f64,
}

impl Area for Rectangle {
    fn area(&self) -> f64 {
        return self.width * self.height;
    }
}

impl Default for Rectangle {
    fn default() -> Self {
        return Rectangle {
            x: 0f64,
            y: 0f64,
            width: 10f64,
            height: 10f64,
        };
    }
}

src/main.rs

use shapes::rect::Rectangle;

mod shapes;

fn main() {
    let rect = Rectangle::default();
}




















The point's are in the Rectangle?

I want to be able to print out the rectangle now... but i don't want Debug print out, i want my own printout!

I want this...

use shapes::rect::Rectangle;

mod shapes;

fn main() {
    let rect = Rectangle::default();

    println!("{}", rect);
}

Lets type this in, and see if someone can tell me what the error is.





















Ok... so implement display?

Lets try it out!

I'll give you one moment. Btw, its std::fmt::Display.





















Complete Code

use std::fmt::Display;

use super::area::Area;

pub struct Rectangle {
    pub x: f64,
    pub y: f64,
    pub width: f64,
    pub height: f64,
}

impl Area for Rectangle {
    fn area(&self) -> f64 {
        return self.width * self.height;
    }
}

impl Default for Rectangle {
    fn default() -> Self {
        return Rectangle {
            x: 0f64,
            y: 0f64,
            width: 10f64,
            height: 10f64,
        };
    }
}

impl Display for Rectangle {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        return write!(
            f,
            "Rectangle({}, {}), {}x{}",
            self.x, self.y, self.width, self.height
        );
    }
}




















Can we do this in TypeScript?





















Complete Code

src/shapes/index.ts

export class Rectangle implements Area {
  constructor(
    public x: number,
    public y: number,
    public width: number,
    public height: number
  ) {}

  area(): number {
    return this.width * this.height;
  }

  toString(): string {
    return `Rectangle(${this.x}, ${this.y}, ${this.width}, ${this.height})`;
  }
}

src/index.ts

import { Rectangle } from "./shapes";

let rect = new Rectangle(5, 5, 10, 20);

console.log(`${rect}`);