diff --git a/.idea/misc.xml b/.idea/misc.xml
index fead741..66727c9 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -38,6 +38,7 @@
+
diff --git a/.idea/rust.iml b/.idea/rust.iml
index 32f1836..0831f61 100644
--- a/.idea/rust.iml
+++ b/.idea/rust.iml
@@ -153,10 +153,15 @@
+
+
+
+
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 24dcbe8..b841b27 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -14,30 +14,36 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
@@ -69,8 +75,6 @@
@@ -153,12 +159,12 @@
-
+
-
+
@@ -192,7 +198,7 @@
-
+
@@ -220,7 +226,7 @@
-
+
@@ -249,13 +255,13 @@
-
+
-
+
-
+
@@ -298,11 +304,11 @@
+
-
@@ -373,20 +379,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -793,10 +785,17 @@
+
+
+
+
+
+
+
-
-
+
+
@@ -808,10 +807,31 @@
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/advanced_traits/Cargo.toml b/advanced_traits/Cargo.toml
new file mode 100644
index 0000000..dc1eb3b
--- /dev/null
+++ b/advanced_traits/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "advanced_traits"
+version = "0.1.0"
+authors = ["Timothy Warren "]
+edition = "2018"
+
+[dependencies]
diff --git a/advanced_traits/src/main.rs b/advanced_traits/src/main.rs
new file mode 100644
index 0000000..9bfffc0
--- /dev/null
+++ b/advanced_traits/src/main.rs
@@ -0,0 +1,151 @@
+use std::fmt;
+use std::ops::Add;
+
+#[derive(Debug, PartialEq)]
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+impl Add for Point {
+ type Output = Point;
+
+ fn add(self, other: Point) -> Point {
+ Point {
+ x: self.x + other.x,
+ y: self.y + other.y,
+ }
+ }
+}
+
+struct Millimeters(u32);
+struct Meters(u32);
+
+/// Implement the Add trait to allow adding
+/// The value from a Meters type to a Millimeters type
+///
+/// The Add allows the cross-type operator overloading
+impl Add for Millimeters {
+ type Output = Millimeters;
+
+ fn add(self, other: Meters) -> Millimeters {
+ Millimeters(self.0 + (other.0 * 1000))
+ }
+}
+
+// ----------------------------------------------------------
+// Fully qualified method calls
+// ----------------------------------------------------------
+
+trait Pilot {
+ fn fly(&self);
+}
+
+trait Wizard {
+ fn fly(&self);
+}
+
+struct Human;
+
+impl Pilot for Human {
+ fn fly(&self) {
+ println!("This is your captain speaking.");
+ }
+}
+
+impl Wizard for Human {
+ fn fly(&self) {
+ println!("Up!");
+ }
+}
+
+impl Human {
+ fn fly(&self) {
+ println!("*waving arms furiously*");
+ }
+}
+
+trait Animal {
+ fn baby_name() -> String;
+}
+
+struct Dog;
+
+impl Dog {
+ fn baby_name() -> String {
+ String::from("Spot")
+ }
+}
+
+impl Animal for Dog {
+ fn baby_name() -> String {
+ String::from("puppy")
+ }
+}
+
+// ----------------------------------------------------------
+// Supertraits
+// ----------------------------------------------------------
+
+/// This trait requires the supertrait, `fmt::Display` to be
+/// implemented to consider itself implemented
+trait OutlinePrint: fmt::Display {
+ fn outline_print(&self) {
+ let output = self.to_string();
+ let len = output.len();
+ println!("{}", "*".repeat(len + 4));
+ println!("*{}*", " ".repeat(len + 2));
+ println!("* {} *", output);
+ println!("*{}*", " ".repeat(len + 2));
+ println!("{}", "*".repeat(len + 4));
+ }
+}
+
+impl OutlinePrint for Point {}
+
+impl fmt::Display for Point {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "({}, {})", self.x, self.y)
+ }
+}
+
+// -------------------------------------------------------------
+// Newtype pattern (Implement external traits on external types)
+// -------------------------------------------------------------
+
+// Wrap an external type in tuple struct, so it is now local
+struct Wrapper(Vec);
+
+// Implement an extenal trait for the now local type
+impl fmt::Display for Wrapper {
+ fn fmt(&self, f: &mut fm::Formatter) -> fmt::Result {
+ write!(f, "[{}]", self.0.join(", "))
+ }
+}
+
+// ----------------------------------------------------------
+
+fn main() {
+ assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
+ Point { x: 3, y: 3 });
+
+ let person = Human;
+
+ // Explicitly specifying which implementation to use
+ Pilot::fly(&person);
+ Wizard::fly(&person);
+
+ // Defaults to the direct implementation
+ // aka: Human::fly(&person);
+ person.fly();
+
+ // Specify the implementation to use for an associated function
+ // implemented multiple ways with the same name
+ println!("A baby dog is called a {}", ::baby_name());
+
+ let display_point = Point { x: 5, y: -3 };
+ display_point.outline_print();
+
+ let w = Wrapper(vec![String::from("hello"), String::from("world")]);
+ println!("w = {}", w);
+}