diff --git a/codes/rust_lang/part08/Cargo.toml b/codes/rust_lang/part08/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..b4fb6388d1fffc2604ffc2367b80b36ab5fc0fc2
--- /dev/null
+++ b/codes/rust_lang/part08/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "part08"
+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/part08/src/custom_int.rs b/codes/rust_lang/part08/src/custom_int.rs
new file mode 100644
index 0000000000000000000000000000000000000000..fa151502b3231e4212b659332e02f3b9e826d2f0
--- /dev/null
+++ b/codes/rust_lang/part08/src/custom_int.rs
@@ -0,0 +1,117 @@
+use crate::minimum::Minimum;
+
+/// Larger ints based on a [Vec] of [u8] to repensent arbitrary lengthy numbers.
+/// The number has a sign as well.
+pub struct CustomInt {
+    /// The data contains the unsigned integers that are read from right to left
+    /// The number 1337 is stored as vec![7, 3, 3, 1]. Each number must be in the range [0,9]
+    /// and no trailing 0s are allowed.
+    data: Vec<u8>,
+    /// Contains the sign of the number +/-1;
+    sign: i8,
+}
+
+impl CustomInt {
+    /// Tries to create a new [CustomInt]. If the number is valid it returns
+    /// an Ok(CustomInt) an Error otherwise.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use part08::custom_int::CustomInt;
+    /// let num = CustomInt::try_new(vec![1, 2, 3, 4], 1);
+    /// assert!(num.is_ok());
+    /// let num = CustomInt::try_new(vec![1, 2, 3, 4], -1);
+    /// assert!(num.is_ok());
+    /// let num = CustomInt::try_new(vec![1, 2, 3, 4], 10);
+    /// assert!(num.is_err());
+    /// let num = CustomInt::try_new(vec![1, 2, 3, 4], -10);
+    /// assert!(num.is_err());
+    /// ```
+    ///
+    pub fn try_new(data: Vec<u8>, sign: i8) -> Result<Self, String> {
+        // EXERCISE:
+        // We don't check for trailing 0s but maybe this could be an exercise.
+        // Also we should check numbers are between 0 and 9.
+        if sign == 1 || sign == -1 {
+            Ok(CustomInt { data, sign })
+        } else {
+            Err(String::from("Invalid sign."))
+        }
+    }
+}
+
+impl Clone for CustomInt {
+    fn clone(&self) -> Self {
+        CustomInt {
+            data: self.data.clone(),
+            sign: self.sign,
+        }
+    }
+}
+
+impl Minimum for CustomInt {
+    // EXERCISE: Correct this function by using clippy and let it guide you.
+    //           Get inspiration from Display to compute the Minimum
+    fn min(self, rhs: Self) -> Self {
+        if self.sign < rhs.sign {
+            return self;
+        } else if self.sign > rhs.sign {
+            return rhs;
+        }
+        if self.data.len() < rhs.data.len() {
+            return self;
+        } else if self.data.len() > rhs.data.len() {
+            return rhs;
+        }
+        for (l, r) in self.data.iter().rev().zip(rhs.data.iter().rev()) {
+            let ls = (*l as i8) * self.sign;
+            let rs = (*r as i8) * self.sign;
+            if ls < rs {
+                return self;
+            } else if ls > rs {
+                return rhs;
+            }
+        }
+        self
+    }
+}
+
+impl PartialEq for CustomInt {
+    fn eq(&self, other: &Self) -> bool {
+        if self.sign == other.sign && self.data.len() == other.data.len() {
+            self.data
+                .iter()
+                .zip(other.data.iter())
+                .try_fold(true, |_, (l, r)| if l == r { Some(true) } else { None })
+                .is_some()
+        } else {
+            false
+        }
+    }
+}
+
+impl std::fmt::Display for CustomInt {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        // This could be replaced by an `?`
+        if self.sign == -1 {
+            if let Err(e) = write!(f, "-") {
+                return Err(e);
+            }
+        }
+
+        // This could be replaced by an `?`
+        let res = self
+            .data
+            .iter()
+            .rev()
+            .try_fold((), |_, t| write!(f, "{}", t));
+        res
+    }
+}
+
+// EXERCISE: write tests
+// EXERCISE: Modify Minimum trait to take references?
+
+#[cfg(test)]
+mod tests {}
diff --git a/codes/rust_lang/part08/src/io.rs b/codes/rust_lang/part08/src/io.rs
new file mode 100644
index 0000000000000000000000000000000000000000..496c227a0a46ba1cbecd6488b2eede64a61b3e3c
--- /dev/null
+++ b/codes/rust_lang/part08/src/io.rs
@@ -0,0 +1,57 @@
+use std::io::BufRead;
+
+use crate::custom_int::CustomInt;
+
+/// Reads i32 from the command line and returns a [Vec] containing
+/// these numbers. Returns errors when the parsing fails.
+pub fn read_command_line() -> Result<Vec<i32>, String> {
+    let mut v = Vec::new();
+    let stdin = std::io::stdin();
+    println!("Enter a list of numbers, one per line. End with Ctrl-D (Linux) or Ctrl-Z (Windows).");
+
+    for line in stdin.lock().lines() {
+        let line = match line {
+            Ok(l) => l,
+            Err(_) => {
+                return Err(String::from("Could not read line"));
+            }
+        };
+
+        match line.trim().parse::<i32>() {
+            Ok(num) => v.push(num),
+            Err(_) => {
+                return Err(String::from("Could not parse integer"));
+            }
+        }
+    }
+    Ok(v)
+}
+
+// EXERCISE: Rewrite using ?
+pub fn read_command_line_custom_int() -> Result<Vec<CustomInt>, String> {
+    let v = vec![
+        CustomInt::try_new(vec![1, 3, 6, 9], 1).unwrap(),
+        CustomInt::try_new(vec![2, 4, 2, 1], -1).unwrap(),
+        CustomInt::try_new(vec![7, 4, 5, 3], 1).unwrap(),
+        CustomInt::try_new(vec![4, 1, 1, 1], -1).unwrap(),
+    ];
+    Ok(v)
+}
+
+/// Prints all the elements of the `tab`.
+/// Tab is borrowed here
+pub fn print_tab(tab: &Vec<i32>) {
+    for t in tab {
+        print!("{} ", t);
+    }
+    println!();
+}
+
+/// Prints all the elements of the `tab`.
+/// Tab is borrowed here
+pub fn print_tab_CustomInt(tab: &Vec<CustomInt>) {
+    for i in tab {
+        println!("{i} ");
+    }
+    println!();
+}
diff --git a/codes/rust_lang/part08/src/lib.rs b/codes/rust_lang/part08/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ac338352b68eb4d8969338dd79c3da95fa16d62c
--- /dev/null
+++ b/codes/rust_lang/part08/src/lib.rs
@@ -0,0 +1,67 @@
+/*!
+part08 illustrates the use of [Vec] and the Error Handling with [Option] and [Result].
+It also showcases struct enums.
+*/
+
+pub mod custom_int;
+pub mod io;
+mod minimum;
+pub mod something_or_nothing;
+
+#[cfg(test)]
+mod tests {
+    use crate::minimum::Minimum;
+    use crate::something_or_nothing::{find_min, SomethingOrNothing};
+
+    #[test]
+    fn test_creation() {
+        let n1: SomethingOrNothing<i32> = SomethingOrNothing::default();
+        assert!(n1 == SomethingOrNothing::default());
+        let n2: SomethingOrNothing<i32> = SomethingOrNothing::new(1);
+        assert!(n2 == SomethingOrNothing::new(1));
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_failure_creation() {
+        let n2: SomethingOrNothing<i32> = SomethingOrNothing::new(1);
+        assert!(n2 == SomethingOrNothing::default());
+        assert!(n2 == SomethingOrNothing::new(2));
+    }
+
+    #[test]
+    fn test_min() {
+        let a = vec![1, 5, -1, 2, 0, 10, 11, 0, 3];
+        let min = find_min(&a);
+        assert!(min == SomethingOrNothing::new(-1));
+    }
+
+    #[test]
+    fn test_min_empty() {
+        let a: Vec<i32> = vec![];
+        let min = find_min(&a);
+        assert!(min == SomethingOrNothing::default());
+    }
+
+    #[test]
+    fn test_min_i32() {
+        let x = 5;
+        let y = 10;
+        assert_eq!(Minimum::min(x, y), x);
+        assert_eq!(Minimum::min(y, x), x);
+        assert_eq!(Minimum::min(x, x), x);
+        assert_eq!(Minimum::min(y, y), y);
+    }
+
+    #[test]
+    fn test_min_something_or_nothing() {
+        let x = SomethingOrNothing::new(5i32);
+        let y = SomethingOrNothing::new(10i32);
+        let z = SomethingOrNothing::default();
+        assert!(x.min(y) == x);
+        assert!(y.min(x) == x);
+        assert!(z.min(y) == y);
+        assert!(y.min(z) == y);
+        assert!(z.min(z) == z);
+    }
+}
diff --git a/codes/rust_lang/part08/src/main.rs b/codes/rust_lang/part08/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4a028c00099da36cb7f45343536e6c24076e08ee
--- /dev/null
+++ b/codes/rust_lang/part08/src/main.rs
@@ -0,0 +1,16 @@
+use part08::io;
+use part08::something_or_nothing::find_min;
+
+fn main() -> Result<(), String> {
+    let tab = match io::read_command_line_custom_int() {
+        Ok(tab) => tab,
+        Err(s) => return Err(s),
+    };
+    println!("Among the Big Ints in the list:");
+    io::print_tab_CustomInt(&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();
+    Ok(())
+}
diff --git a/codes/rust_lang/part08/src/minimum.rs b/codes/rust_lang/part08/src/minimum.rs
new file mode 100644
index 0000000000000000000000000000000000000000..fd524a1b6d36c0f09f39d78854f93ba69cfc730b
--- /dev/null
+++ b/codes/rust_lang/part08/src/minimum.rs
@@ -0,0 +1,15 @@
+// If we remove Copy, we have a problem with the t in tab
+// in the computation of the minimum.
+pub trait Minimum: Clone {
+    fn min(self, rhs: Self) -> Self;
+}
+
+impl Minimum for i32 {
+    fn min(self, rhs: Self) -> Self {
+        if self < rhs {
+            self
+        } else {
+            rhs
+        }
+    }
+}
diff --git a/codes/rust_lang/part08/src/something_or_nothing.rs b/codes/rust_lang/part08/src/something_or_nothing.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ce9af04719e495fb0a2341c929cfe3ba3becd22b
--- /dev/null
+++ b/codes/rust_lang/part08/src/something_or_nothing.rs
@@ -0,0 +1,78 @@
+use std::fmt::Display;
+
+use crate::minimum::Minimum;
+
+/// An generic enumerated type that encapsulates and Option<T>.
+#[derive(Clone, Copy)]
+pub struct SomethingOrNothing<T>(Option<T>);
+
+impl<T: Minimum + Display> SomethingOrNothing<T> {
+    pub fn new(val: T) -> Self {
+        SomethingOrNothing(Some(val))
+    }
+    /// A static function that prints the content of a SomethingOrNothing.
+    pub fn print(&self) {
+        match &self.0 {
+            None => println!("Nothing."),
+            Some(val) => println!("Something is: {}", val),
+        }
+    }
+}
+
+impl<T> Default for SomethingOrNothing<T> {
+    /// By Default a [SomethingOrNothing] is a nothing.
+    fn default() -> Self {
+        SomethingOrNothing(None)
+    }
+}
+
+impl<T: PartialEq + Minimum> PartialEq for SomethingOrNothing<T> {
+    fn eq(&self, other: &Self) -> bool {
+        match (&self.0, &other.0) {
+            (None, None) => true,
+            (Some(lhs), Some(rhs)) => lhs == rhs,
+            _ => false,
+        }
+    }
+}
+
+impl<T: Minimum + Display> Minimum for SomethingOrNothing<T> {
+    fn min(self, rhs: Self) -> Self {
+        match (self.0, rhs.0) {
+            (None, None) => SomethingOrNothing(None),
+            (Some(lhs), Some(rhs)) => SomethingOrNothing::new(lhs.min(rhs)),
+            (None, Some(rhs)) => SomethingOrNothing::new(rhs),
+            (Some(lhs), None) => SomethingOrNothing::new(lhs),
+        }
+    }
+}
+
+/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
+/// Returns a [Some] containing the the minimum value
+/// or [None] if no minimum value was found.
+///
+/// # Examples
+///
+/// ```
+/// # use part08::something_or_nothing::{SomethingOrNothing, find_min};
+/// # fn main() {
+/// let tab = vec![10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let min = find_min(&tab);
+/// assert!(min == SomethingOrNothing::new(2));
+/// # }
+/// ```
+///
+/// ```
+/// # use part08::something_or_nothing::{SomethingOrNothing, find_min};
+/// # fn main() {
+/// let tab: Vec<i32> = vec![];
+/// let min = find_min(&tab);
+/// assert!(min == SomethingOrNothing::default());
+/// # }
+/// ```
+pub fn find_min<T: Minimum + Display>(tab: &Vec<T>) -> SomethingOrNothing<T> {
+    // A very elegant fold applied on an iterator
+    tab.iter().fold(SomethingOrNothing::default(), |res, x| {
+        res.min(SomethingOrNothing::new(x.clone()))
+    })
+}