Ref - https://doc.rust-lang.org/book/ch10-02-traits.html

Traits are similar to interfaces in Java/JS. They let you define the shape / interface of what you’re building

trait Shape {
    fn area(&self) -> f32;
}

Structs cam implement these traits

struct Rect {
    width: f32,
    height: f32
}

impl Shape for Rect {
    fn area(&self) -> f32 {
        return self.width * self.height
	  }
}

You can define a function that takes in any struct that implements this trait

	 
 fn get_area(shape: impl Shape) -> f32 {
    return shape.area()
 }

Or

 fn get_area_2<T: Shape>(shape: T) -> f32 {
    return shape.area()
 }

Or

fn get_area_3<T>(shape: T) -> f32
    where T: Shape 
{
        return shape.area()
}