diff --git a/codes/rust_lang/part03/Cargo.toml b/codes/rust_lang/part03/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..005d5bb3302af663c1014626a93d7e9a51cfa26a
--- /dev/null
+++ b/codes/rust_lang/part03/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "part03"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/codes/rust_lang/part03/src/main.rs b/codes/rust_lang/part03/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7cadbdc27915aa2495b46109fc526c770519620e
--- /dev/null
+++ b/codes/rust_lang/part03/src/main.rs
@@ -0,0 +1,103 @@
+/// In part03 we introduce genericity through traits and in particular, [Copy],
+/// [Clone], [std::fmt::Display] .
+
+enum SomethingOrNothing<T> {
+    Nothing,
+    Something(T),
+}
+
+// We know the generic type T must be Displayable
+impl<T: std::fmt::Display> SomethingOrNothing<T> {
+    // Static function
+    fn print(self) {
+        match self {
+            SomethingOrNothing::Nothing => println!("Nothing."),
+            SomethingOrNothing::Something(val) => println!("Something is: {}", val),
+        }
+    }
+}
+
+impl<T: Clone> Clone for SomethingOrNothing<T> {
+    fn clone(&self) -> Self {
+        match self {
+            SomethingOrNothing::Nothing => SomethingOrNothing::Nothing,
+            SomethingOrNothing::Something(val) => SomethingOrNothing::Something(val.clone()),
+        }
+    }
+}
+
+impl<T: Copy> Copy for SomethingOrNothing<T> {}
+
+// If we remove Copy, we have a problem with the t in tab
+// in the computation of the minimum.
+trait Minimum: Copy {
+    fn min(self, rhs: Self) -> Self;
+}
+
+impl<T: Minimum> Minimum for SomethingOrNothing<T> {
+    fn min(self, rhs: Self) -> Self {
+        match (self, rhs) {
+            (SomethingOrNothing::Nothing, SomethingOrNothing::Nothing) => {
+                SomethingOrNothing::Nothing
+            }
+            (SomethingOrNothing::Something(lhs), SomethingOrNothing::Something(rhs)) => {
+                SomethingOrNothing::Something(lhs.min(rhs))
+            }
+            (SomethingOrNothing::Nothing, SomethingOrNothing::Something(rhs)) => {
+                SomethingOrNothing::Something(rhs)
+            }
+            (SomethingOrNothing::Something(lhs), SomethingOrNothing::Nothing) => {
+                SomethingOrNothing::Something(lhs)
+            }
+        }
+    }
+}
+
+// i32 is Copyable as a very basic type as f32, f64, etc.
+// Arrays for example are not copyable.
+impl Minimum for i32 {
+    fn min(self, rhs: Self) -> Self {
+        if self < rhs {
+            self
+        } else {
+            rhs
+        }
+    }
+}
+
+const SIZE: usize = 9;
+
+fn read_command_line() -> [i32; SIZE] {
+    [10, 32, 12, 43, 52, 53, 83, 2, 9]
+}
+
+// Prints tab and returns tab.
+// Tab would be destructed at the end of the function otherwise.
+fn print_tab(tab: [i32; SIZE]) -> [i32; SIZE] {
+    for t in tab {
+        print!("{} ", t);
+    }
+    println!();
+    tab
+}
+
+fn find_min<T: Minimum>(tab: [T; SIZE]) -> ([T; SIZE], SomethingOrNothing<T>) {
+    let mut min = SomethingOrNothing::Nothing;
+    // Here is T is not Copyable tab is consumed and cannot be returned
+    for t in tab {
+        min = min.min(SomethingOrNothing::Something(t));
+    }
+    (tab, min)
+}
+
+fn main() {
+    let tab = read_command_line();
+
+    println!("Among the Somethings in the list:");
+    let tab = print_tab(tab);
+
+    // There are alternatives to access fields of tuples
+    let (_, min) = find_min(tab);
+    // The first field is not used therefore we can replace it with "_"
+    min.print();
+}