diff --git a/PLANNING.md b/PLANNING.md
new file mode 100644
index 0000000000000000000000000000000000000000..0257a27308c2bc119e23797a227941b1027e26c4
--- /dev/null
+++ b/PLANNING.md
@@ -0,0 +1,37 @@
+# Préquel
+
+- [] Installation du cours.
+
+# Jour
+
+- [] Lundi matin (9h-10h15, 10h45-12h): 
+    - Vérification install, et Hello world.
+    - part00 à part01
+- [] Lundi après-midi (13h-14h15, 14h45-16h): 
+    - part02
+- [] Mardi matin (9h-10h15, 10h45-12h):
+    - part03
+- [] Mardi après-midi (13h-14h15, 14h45-16h): 
+    - part04
+- [] Mercredi matin (9h-10h15, 10h45-12h): 
+    - part05, part06
+- [] Mercredi après-midi (13h-14h15, 14h45-16h): 
+    - Gestion d'erreurs
+    - Lambda
+- [] Jeudi matin (9h-10h15, 10h45-12h): 
+    - Collections (Vec, String, HashMap)
+    - Itérateurs
+- [] Jeudi après-midi (13h-14h15, 14h45-16h): 
+    - CLI
+    - Lifetimes
+- [] Vendredi matin (9h-10h15, 10h45-12h): 
+    - Unsafe Rust
+- [] Vendredi après-midi (13h-14h15, 14h45-16h): 
+    - Choix du projet et groupes
+
+# Soir
+
+Lundi (17h-21h): Vérification install, et Hello world & part00 à part01
+Mardi (17h-21h): part02 & part03
+Mercredi (17h-21h): part04, part 05 & part 06
+Jeudi (17h-21h): Gestion d'erreurs, Lambda, Collections & Itérateurs
\ No newline at end of file
diff --git a/README.md b/README.md
index e003c31f848c97fec980a12c4f97b7fe40cb6935..a9030a7ac57813f3894ed6e63b8b2953f79e7743 100644
--- a/README.md
+++ b/README.md
@@ -182,12 +182,13 @@ Le cours théorique est découpé comme suit:
 4. Ownership, Borrowing.
 5. Modules et visibilité.
 6. Tests, documentation, outils variés (rustfmt, clippy, etc).
-7. Vec, Gestion d'erreurs (Option, Result). Intro basique à l'io
-8. Itérateurs
-9. String,
-10. Smart pointeurs (Rc principalement) et mutabilité intérieure.
-11. CLI, I/O.
-12. Unsafe Rust, Box, etc.
-13. FFI
+7. Gestion d'erreurs (Option, Result).
+8. Closures (Fonctions anonymes)
+9. Collections (Vec, String, HashMap)
+10. Itérateurs
+11. Smart pointeurs (Rc principalement) et mutabilité intérieure.
+12. CLI, I/O.
+13. Unsafe Rust, Box, etc.
+14. FFI
 
 <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />Ce(tte) œuvre est mise à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Licence Creative Commons Attribution -  Partage dans les Mêmes Conditions 4.0 International</a>.
diff --git a/book/src/part07.md b/book/src/part07.md
index 1c0d27e7b00007f2e2aa98ff166ddf4fccd4c6c3..e005278c9d48bdde62c2e81e551b6e0cfa4db58e 100644
--- a/book/src/part07.md
+++ b/book/src/part07.md
@@ -1 +1,391 @@
 # Discussion du code `part07`
+
+## Concepts
+
+Les concepts abordés dans cet exemple sont:
+
+- [Discussion du code `part07`](#discussion-du-code-part07)
+  - [Concepts](#concepts)
+  - [Documentation](#documentation)
+  - [Discussion](#discussion)
+    - [Les différents types d'erreurs](#les-différents-types-derreurs)
+      - [Erreurs rattrapables](#erreurs-rattrapables)
+      - [Erreurs irrattrapables](#erreurs-irrattrapables)
+    - [Le type Option](#le-type-option)
+    - [La macro panic!](#la-macro-panic)
+    - [Le type Result](#le-type-result)
+    - [L'opérateur ?](#lopérateur-)
+
+## Documentation
+
+Afin de compléter ce cours, je vous recommande la lecture des ressources suivantes :
+
+- [La gestion des erreurs en Rust](https://doc.rust-lang.org/book/ch09-00-error-handling.html)
+- [Les options](https://doc.rust-lang.org/std/option)
+- [Les résultats](https://doc.rust-lang.org/std/result)
+- [La macro panic](https://doc.rust-lang.org/stable/std/macro.panic.html)
+- [Le trait Try et l'opérateur ?](https://doc.rust-lang.org/stable/std/ops/trait.Try.html)
+
+## Discussion
+
+Lors de l'exécution d'un programme, il existe en général une multitude d'endroits où des erreurs peuvent se produire. Il est important de savoir identifier 
+les différents types d'erreurs, ainsi que les outils offerts par le langage Rust permettant de gérer ces erreurs.
+
+### Les différents types d'erreurs
+
+Il faut savoir différentier deux principaux types d'erreurs. 
+
+#### Erreurs rattrapables
+
+Dans un premier temps, il y a les erreurs rattrapables ou prévues.
+En général, ces erreurs surviennent lorsque l'utilisateur entre des données erronées.
+
+Nous avons par exemple :
+
+- Le chemin d'un fichier fourni par l'utilisateur qui n'existe pas
+- Une entrée invalide, p.ex une lettre à la place d'un nombre
+- De mauvais identifiants pour la connexion à un serveur 
+
+Ces erreurs sont attendues, il est donc normal d'anticiper leurs occurences, et par conséquent, de s'y préparer.
+Elles de ne devraient pas interrompre l'exécution du programme.
+
+Pour détecter ce type d'erreur, nous devons essayer de prévoir tous les scénarios possibles.
+Si je demande à l'utilisateur d'entrer une valeur comprise entre 1 et 10, je pourrais par exemple obtenir :
+
+- Une valeur non-numérique
+- Une valeur non comprise dans l'intervalle demandée
+- L'absence de valeur
+- Une erreur impossible à prévoir parce qu'on ne peut pas tout prévoir.
+Le meilleur moyen de se prémunir de ce genre d'erreur, consiste à utiliser des types adaptés.
+
+Prenons par exemple la fonction :
+
+```rust,no_run
+fn make_color(red:i32, green:i32, blue:i32, alpha:i32) -> i32 {
+    red << 24 | green << 16 | blue << 8 | alpha // Quel est le problème?
+}
+```
+
+Cette fonction prend en argument une valeur par canal de couleur et construit
+un entier représentant une couleur rgba 32 bit.
+Le problème majeur dans cette fonction est le typage de nos arguments. Pour fabriquer une couleur rgba 32 bit, 
+il faut un octet par canal. Le type `i32` n'est donc pas approprié, il pourrait être la source d'erreurs.
+
+Pour éviter cela, on pourrait par exemple le remplacer par `u8` qui permet de représenter un octet.
+
+```rust,no_run
+fn make_color(red:u8, green:u8, blue:u8, alpha:u8)->u32 {
+    (red as u32) << 24 | (green as u32) << 16 | (blue as u32) << 16 | (alpha as u32)
+}
+```
+
+De cette manière, on évite les erreurs potentielles à la source. Vous noterez qu'il est nécessaire
+de caster vos arguments, afin d'avoir une expression cohérente du point de vue des types. Notre code
+est donc moins susceptible de contenir une erreur, mais en contrepartie, il est plus complexe.
+
+#### Erreurs irrattrapables
+
+Le deuxième type d'erreurs que l'on peut rencontrer sont les erreurs irrattrapables (les bugs par exemple).
+
+Lorsque de notre programme se trouve dans un état incohérent, il est nécessaire d’interrompre son exécution.
+De manière générale, les bugs surviennent lorsque le développeur a fait une erreur dans son code. Il existe 
+plusieurs erreurs possibles. Nous avons par exemple des erreurs :
+
+- algorithmiques (ex: un faute logique dans la conception de l'algorithme, un cas pas couvert)
+- du système (ex: la carte réseau n'est pas accessible)
+- humaines (ex: le développeur a fait une faute d'inattention en écrivant son code) 
+
+Il faut à tout prix éviter ces erreurs au maximum. Un programme qui interrompt constamment son exécution,
+n'est pas un programme robuste et par conséquent, un programme qui n'est pas fiable.
+La notion de fiabilité dépasse le cadre de ce cours, mais nous pouvons dire pour résumer qu'il existe plusieurs 
+domaines et donc plusieurs niveau d'attente en terme de fiabilité. Il arrive souvent qu'un jeu soit buggé dans ses
+premières versions. En revanche, il est n'est pas acceptable que le pilote automatique d'un avion crash au en plein 
+milieu d'un vol.
+
+### Le type Option
+
+Historiquement, on représentait l'absence de valeur par une valeur dédiée (p.ex : une personne qui n'a pas
+renseigné son âge, possède un âge de -1, ou alors l'utilisation du pointeur `NULL`). Bien que cette solution fonctionne, elle peut-être la source de
+nombreuses erreurs et bugs en tout genre. Un type optionnel est une alternative moderne et plus robuste pour
+nombreuses erreurs et bugs en tout genre. Les langages modernes gèrent ces cas à l'aide de leur système de typage permettant de meilleures vérifications à la compilation et à l'exécution ce qui les rend plus robustes: on parle de types *optionnels*.
+
+Il existe un grand nombre de fonctions qui ne retournent pas forcèment un résultat. On peut également penser à
+des structures. Le caractère optionnel d'une valeur n'est pas forcèment une erreur, mais si cet aspect n'est 
+pas géré correctement, il peut mener à des erreurs.
+
+Nous pouvons par exemple vouloir représenter un utilisateur qui peut s'il le veut fournir sa date de naissance
+et son adresse email. Prenons la structure suivante :
+
+```rust,ignore
+struct User {
+    username: String,
+    birth_date: i32,
+    email: String,
+}
+```
+
+Si on souhaite récupérer l'une de ces deux informations, on pourrait se retrouver dans un cas où l'utilisateur n'a pas
+souhaité renseigner l'information désirée. C'est là qu'intervient le type `Option<T>`. Il permet de représenter une valeur
+optionnelle.
+
+Voici sa déclaration d'après la documentation Rust :
+
+```rust
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+```
+
+C'est tout simplement d'un type énuméré qui contient soit une valeur sous la forme `Some(ma_valeur)` ou pas de valeur `None`. Il s'agit de la version générique du type `NumberOrNothing` vu dans la [partie 2](./part02.md).
+
+Nous pouvons donc réecrire notre structure `User` de cette manière :
+
+```rust,ignore
+struct User {
+    username: String,
+    birth_date: Option<i32>,
+    email: Option<String>,
+}
+```
+
+Si nous reprenons notre exemple du minimum d'un tableau, nous pouvons écrire notre fonction de la manière suivante :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part07/src/find_minimum.rs:min_with_option}}
+```
+
+Ici on commence par instancier notre minimum à `None`, puis on compare itérativement notre minimum avec
+les valeurs du tableau encapsulées dans une option avec `Some(*t)`.
+
+Pour comparer deux options entre elles, nous avons implémenté le trait minimum pour une `Option<T>`, où `T`
+implémente le trait minimum. Ce qui nous donne : 
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part07/src/minimum.rs:min_for_option}}
+```
+
+On peut voir ici que l'on décompose notre option grâce au pattern matching de Rust.
+
+### La macro panic!
+
+Un programme peut être amené à s'arrêter de manière anormale. En `C`, on utilise la fonction `abort`. 
+Cette dernière va indiquer au processus parent ayant exécuté le programme qu'une erreur s'est produite et que
+l'exécution ne peut pas se poursuivre.
+
+En Rust, il est possible de mettre fin au programme d'une manière similaire à
+ce que l'on retrouve en `C` avec la fonction suivante :
+
+```rust,should_panic
+use std::process;
+
+fn main() {
+    process::abort();
+}
+```
+
+Néanmoins, Rust étant un langage moderne, il possède la macro `panic!`. Cette maco ne va pas simplement interrompre
+l'exécution du programme et signaler une erreur au processus appelant. Par défaut,
+elle va également remonter la pile des appels de fonctions et libérer la mémoire au fur à mesure.
+
+Pour déclencher une panique du programme, il suffit d'appeler la macro avec un message en argument :
+
+```rust,should_panic
+fn main() {
+    panic!("!!! Oups something went wrong !!!")
+}
+```
+
+Si on exécute ce code, on obtient l'erreur suivante :
+
+```console
+   Compiling playground v0.0.1 (/playground)
+    Finished dev [unoptimized + debuginfo] target(s) in 0.41s
+     Running `target/debug/playground`
+thread 'main' panicked at '!!! Oups something went wrong !!!', src/main.rs:2:5
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+```
+
+On peut voir que la console nous indique que le fil d'exécution principal `main` a paniqué, et il nous affiche le message
+que nous avons passé en argument à notre macro `panic!`.
+
+Si nous reprenons notre exemple du minimum d'un tableau, nous pouvons écrire notre fonction de la manière suivante :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part07/src/find_minimum.rs:min_with_panic}}
+```
+
+La première chose que nous pouvons noter avec notre fonction est le type de retour. En effet, nous ne retournons pas
+une option, mais bien un élèment de type T. En effet, si on est **certain** que notre fonction va retourner un élément,
+il n'y a pas de raison d'encapsuler ce retour dans une strucutre quelconque.
+
+Si **malgré** notre certitude, la fonction ne parvenait pas à produire de résultat, nous serions alors dans un cas indertimné,
+et par conséquent il faut mettre fin à l'exécution du programme. Pour cela, on peut voir dans la dernière expression que 
+si le minimum n'a pas été trouvé `None => panic!("The array is empty"),`, alors le programme se termine sur une panic.
+
+Le message d'erreur passé en argument est remonté plus haut. Il est en effet possible d'intercepter les panic
+grâce à la fonction `std::panic::catch_unwind` ou en rédéfissant manuellement le comportement de la macro `panic!` à l'aide
+de la fonction `std::panic::set_hook`. Néanmoins, l'usage de ces fonctions devrait être limité à des cas très spécifiques
+que nous ne couvrirons pas dans ce cours d'introduction au Rust.
+
+Le développeur néophyte pourrait être tenté de *simplifier* (dans le sens du nombre de caractères) son code en utilisant 
+uniquement la macro `panic!`. Cela va à l'encontre des bonnes pratiques du Rust et aura tendance à rendre
+votre code peu compréhensible et défaillant. Je vous recommande cet excellent [article](https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-panic.html) de la documentation Rust qui explique quand utiliser la macro `panic!` à bon escient.
+
+En résumé, la macro `panic` devrait être utilisé à des fins de debugging ou uniquement lorsque le programme rentre dans 
+un état indeterminé, c'est à dire un erreur irrattrapable.
+
+### Le type Result
+
+Le Rust offre une solution plus élégante que d'interrompre l'exécution du programme pour gérer les erreurs. Il s'agit
+comme pour `Option<T>` d'un type énuméré. Voici sa définition :
+
+```rust
+enum Result<T, E> {
+   Ok(T),
+   Err(E),
+}
+```
+
+Le type `Result<T,E>` peut contenir soit une valeur attendue en cas de réussite sous la forme d'un `Ok(ma_valeur)`, ou
+valeur permettant de renseigner l'erreur sur forme de `Err(mon_erreur)`. C'est un type plus complet qu'une simple
+`Option<T>`, car en cas d'absence de valeur, nous pouvons indiquer la cause de l'erreur.
+
+Prenons par exemple la fonction suivante qui permet de télécharger une page WEB :
+
+```rust,ignore
+fn get_html(uri: String) -> String
+```
+
+Un problème pourrait se produire lors du téléchargement. On pourrait donc écrire :
+
+```rust,ignore
+fn get_html(uri: String) -> Option<String>
+```
+
+Si notre fonction nous retourne `None`, on se rend compte très vite que l'on a aucune information sur la
+raison de l'absence de données (pas de connexion, mauvaise url, accès interdit, etc...).
+
+C'est là qu'intervient le type `Result<T,E>`, en cas d'absence de résultat de la fonction, nous allons pouvoir
+comprendre la source de l'erreur et réagir réagir en conséquence. Nous pourrions donc écrire :
+
+```rust,ignore
+enum DownloadError {
+  BadURL,
+  Forbidden,
+  ...
+}
+fn get_html(uri: String) -> Result<String, DownloadError>
+```
+
+Reprenons maintenant notre exemple du minimum d'un tableau. La première chose que nous pouvons faire est de définir
+type représentant les erreurs que nous pourrions rencontrer en cherchant le minimum :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part07/src/find_minimum.rs:find_min_error}}
+```
+
+Ici nous envisageons deux scénarios pouvant provoquer une erreur :
+
+- Le minimum d'une liste vide
+- Une éventuelle erreur que nous n'aurions pas encore prévu. Cette erreur est accompagnée d'un message 
+décrivant l'erreur.
+
+Une fois nos erreurs définies, nous pouvons passer à l'implémentation de notre fonction de recherche du minimum :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part07/src/find_minimum.rs:min_with_result}}
+```
+
+Cette fonction n'est pas très différente des précédentes. On remarque à la fin que pour former un `Result`,
+si nous trouvons un minimum, nous l'encapsulons dans un `Ok(...)`, sinon nous retournons une erreur avec `Err(...)`.
+Ici la seule erreur que nous retournons est la liste vide.
+
+Pour traiter ce résultat, nous pouvons faire du pattern matching :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part07/src/main.rs:parse_result}}
+```
+
+Ici nous avons trois cas :
+
+- le minimum a été trouvé, on l'affiche.
+- la liste était vide, on affiche un message d'erreur.
+- le minimum n'a pas pu être trouvé à cause d'une erreur non gérée, le programme va donc se terminer sur
+une panic contenant le message d'erreur retourné par la fonction.
+
+Il est commun de rencontrer un usage pouvant mener facilement à des erreurs de `Result`. Prenons par exemple
+`Result<T, String>` ou `Result<T, i32>`. En règle général, ces types concrets permettent de retourner 
+un message ou un code en cas d'erreur. Bien que cela ne pose pas de problème du point de vue purement fonctionel, 
+il rend aveugle le compilateur. En effet, en définissant les erreurs attendues avec un type énuméré, le compilateur
+peut s'assurer que toutes les erreurs ont été prises en compte lors d'une décomposition de l'erreur.
+
+Prenons l'exemple suivant :
+
+```rust,ignore
+fn foo() -> Result<i32, String>{
+  // do stuff
+  match val {
+    1 => Ok(42),
+    2 => Err("Oupsi"),
+    3 => Err("G phai une faute"),
+    _ => Err("Aie aie aie")
+  }
+}
+```
+
+Imaginons que j'aie fait une faute dans mon message d'erreur. Mon message d'erreur est le seul moyen de différencier
+les différentes erreurs possibles. En corrigeant ma faute, je dois maintenant mettre à jour **tout mon code**, ainsi
+que le **code de tous ceux qui utilisent mon code**. Je peux également me tromper sur la casse de mon message d'erreur
+la ponctuation etc... Le compilateur ne verra pas l'erreur et je peux passer des heures à chercher pourquoi mon 
+code ne marche pas.
+
+Il en va de même avec les codes d'erreurs numériques, il suffit que je veuille changer un seul code pour devoir à
+nouveau mettre tout à jour.
+
+Il est donc fortement recommandé d'éviter cet usage du type `Result`.
+
+Néanmoins, l'usage de type énuméré pour la gestion des erreurs peut-être source de redondance. On se retrouve avec
+des types qui représentent les mêmes erreurs avec des noms différents dans chaque crate. Pour éviter cela, il est
+préférable de commencer par chercher si son erreur existe avant de créer une nouvelle erreur. Cela dépasse le cadre
+de ce cours, mais sachez qu'il existe deux crates populaires qui peuvent vous aider pour la gestion d'erreur :
+
+- [anyhow](https://docs.rs/anyhow/latest/anyhow/)
+- [thiserror](https://docs.rs/thiserror/latest/thiserror/)
+
+### L'opérateur ?
+
+Le language Rust offre un sucre syntaxique, afin de simplifier la gestion des options et des erreurs imbriquées.
+L'opérateur `?` permet de récupérer la valeur contenue ou faire remonter l'erreur ou l'absence de valeur. On s'en sert
+principalement pour les `Option` et les `Result`. Pour plus de détails sur l'interface `Try` qui permet d'utiliser
+l'opérateur `?` sur un type quelconque, je vous recommande [la documentation](https://doc.rust-lang.org/std/ops/trait.Try.html).
+
+Prenons un exemple directement tiré de notre code :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part07/src/find_minimum.rs:min_two_tabs_hand}}
+```
+
+Cette fonction prends deux tableaux en argument et va chercher quelle est la valeur minimum globale.
+Si on veut réutiliser le code que nous avons déjà écrit, nous avons une fonction qui retourne un
+`Result` et qui nous donne la valeur minimale d'un tableau. Il nous suffit donc de chercher la  valeur
+minimale dans le premier tableau, puis dans le deuxième, et enfin retourner la plus petite des deux
+valeurs.
+
+Seulement, ce n'est pas aussi simple puisque l'on obtient un `Result` pour chaque fonction, il faut
+systèmatiquement verifier qu'aucune erreur s'est produite. Ici, si une erreur est survenue, nous 
+n'avons rien d'autre à faire que de retourner l'erreur telle quelle.
+
+C'est en réalité un cas de figure que l'on retrouve souvent. On peut voir dans notre code ci-dessus,
+le code est répetitif et rends le code la fonction moins lisible.
+
+Avec l'opérateur `?` on peut simplement remplacer le test ainsi :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part07/src/find_minimum.rs:min_two_tabs_qm}}
+```
+
+Ces deux fonctions font strictement la même chose. L'opérateur agit comme un sucre syntaxique qui permet
+d'allèger l'écriture du code et ainsi augmenter sa lisibilité. En clair, si le résultat est `Ok(val)`, 
+l'expression retourne `val`, sinon la fonction se termine ici et retourne le résultat `Err(error)` contenu
+dans le résultat.
\ No newline at end of file
diff --git a/codes/run_tests.sh b/codes/run_tests.sh
index 004243133f23544a0a15a76b3337034228ea37a9..db25ede748c7da8382b957a17f9c4f9da3dbe018 100755
--- a/codes/run_tests.sh
+++ b/codes/run_tests.sh
@@ -4,12 +4,7 @@ make -C c_lang/min_list
 cd rust_lang
 for d in *; do
     echo ==================== Running cargo run for $d  ====================
-    if [ $d == 'part07' ]
-    then
-        cargo run --manifest-path $d/Cargo.toml < $d/numbers.txt
-    else
-        cargo run --manifest-path $d/Cargo.toml
-    fi
+    cargo run --manifest-path $d/Cargo.toml
     echo ==================== Running cargo test for $d ====================
     cargo test --manifest-path $d/Cargo.toml --workspace --verbose
     echo ==================== Running cargo doc for $d  ====================
diff --git a/codes/rust_lang/part07/numbers.txt b/codes/rust_lang/part07/numbers.txt
deleted file mode 100644
index 96c95dafa6dc00eb4f7fb393cdf44412e655b7a3..0000000000000000000000000000000000000000
--- a/codes/rust_lang/part07/numbers.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-3478
-26
--127
-1287
-189
\ No newline at end of file
diff --git a/codes/rust_lang/part07/src/find_minimum.rs b/codes/rust_lang/part07/src/find_minimum.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ae0bd089b09a8de93636a6c1df895af21d304605
--- /dev/null
+++ b/codes/rust_lang/part07/src/find_minimum.rs
@@ -0,0 +1,206 @@
+//! Contains the core logic of the library, allowing to tore generic values
+//! (or their absence) and manipulate them.
+//! We demonstrates three kind of way to deal with errors
+
+use crate::minimum::Minimum;
+
+// ANCHOR: find_min_error
+#[derive(PartialEq)]
+pub enum FindMinError {
+    EmptyList,
+    UnsupportedError(String),
+}
+// ANCHOR_END: find_min_error
+
+use crate::find_minimum::FindMinError::EmptyList;
+
+/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
+/// Returns a [Option::Some] containing the the minimum value
+/// or [Option::None] if no minimum value was found.
+///
+/// # Example
+///
+/// ```
+/// # use part07::find_minimum::{find_min_with_option};
+/// # fn main() {
+/// let tab = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let min = find_min_with_option(&tab);
+/// assert!(min == Some(2));
+/// # }
+/// ```
+// ANCHOR: min_with_option
+pub fn find_min_with_option<T: Minimum>(tab: &[T]) -> Option<T> {
+    let mut minimum = None;
+    // Here is T is Copyable. Which means that t is not moved in the loop
+    for t in tab {
+        minimum = Minimum::min(minimum, Some(*t));
+    }
+    minimum
+}
+// ANCHOR_END: min_with_option
+
+/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
+/// Returns a [Result::Ok] containing the minimum value
+/// or an [Result::Err] containing the error, if no minimum value was found.
+///
+/// # Example
+///
+/// ```
+/// # use part07::find_minimum::{find_min_with_result};
+/// # fn main() {
+/// let tab = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let min = find_min_with_result(&tab);
+/// assert!(min == Ok(2));
+/// # }
+/// ```
+///
+/// ```
+/// # use part07::find_minimum::{find_min_with_result};
+/// # fn main() {
+/// let tab : [i32; 0] = [];
+/// let min = find_min_with_result(&tab);
+/// assert!(min.is_err());
+/// # }
+/// ```
+// ANCHOR: min_with_result
+pub fn find_min_with_result<T: Minimum>(tab: &[T]) -> Result<T, FindMinError> {
+    let mut minimum = None;
+    // Here is T is Copyable. Which means that t is not moved in the loop
+    for t in tab {
+        minimum = Minimum::min(minimum, Some(*t));
+    }
+
+    match minimum {
+        Some(val) => Ok(val),
+        None => Err(EmptyList),
+    }
+}
+// ANCHOR_END: min_with_result
+
+/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
+/// Returns a T which is the minimum value
+/// or panics if if no minimum value was found.
+///
+/// # Example
+///
+/// ```
+/// # use part07::find_minimum::{find_min_with_panic};
+/// # fn main() {
+/// let tab = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let min = find_min_with_panic(&tab);
+/// assert!(min == 2);
+/// # }
+/// ```
+///
+/// ```should_panic
+/// # use part07::find_minimum::{find_min_with_panic};
+/// # fn main() {
+/// let tab : [i32; 0] = [];
+/// let _min = find_min_with_panic(&tab);
+/// # }
+/// ```
+// ANCHOR: min_with_panic
+pub fn find_min_with_panic<T: Minimum>(tab: &[T]) -> T {
+    let mut minimum = None;
+    // Here is T is Copyable. Which means that t is not moved in the loop
+    for t in tab {
+        minimum = Minimum::min(minimum, Some(*t));
+    }
+
+    // We decide that we cannot compute the minimum of an empty array
+    match minimum {
+        Some(val) => val,
+        None => panic!("The array is empty"),
+    }
+}
+// ANCHOR_END: min_with_panic
+
+/// Computes the minimum amongst two Arrays of a type T which implements the [Minimum] trait.
+/// Returns a [Result::Ok] containing the minimum value
+/// or an [Result::Err] containing the error, if no minimum value was found.
+///
+/// We deal with errors in underlying function calls without the [?] operator.
+///
+/// # Example
+///
+/// ```
+/// # use part07::find_minimum::{find_min_amongst_arrays_by_hand};
+/// # fn main() {
+/// let tab_a = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let tab_b = [22, 34, 11, 4, 52, 99, 71, 13, 43];
+/// let min = find_min_amongst_arrays_by_hand(&tab_a, &tab_b);
+/// assert!(min == Ok(2));
+/// # }
+/// ```
+///
+/// ```
+/// # use part07::find_minimum::{find_min_amongst_arrays_by_hand};
+/// # fn main() {
+/// let tab_a = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let tab_b : [i32; 0] = [];
+/// let min = find_min_amongst_arrays_by_hand(&tab_a, &tab_b);
+/// assert!(min.is_err());
+/// # }
+/// ```
+// ANCHOR: min_two_tabs_hand
+pub fn find_min_amongst_arrays_by_hand<T: Minimum>(
+    lhs: &[T],
+    rhs: &[T],
+) -> Result<T, FindMinError> {
+    let min_result = find_min_with_result(lhs);
+    let min_l = if let Ok(x) = min_result {
+        x
+    } else {
+        // Since tmp is not Ok, we return the error to the caller
+        return min_result;
+    };
+
+    let min_result = find_min_with_result(rhs);
+    let min_r = if let Ok(x) = min_result {
+        x
+    } else {
+        // Since tmp is not Ok, we return the error to the caller
+        return min_result;
+    };
+
+    Ok(min_l.min(min_r))
+}
+// ANCHOR_END: min_two_tabs_hand
+
+/// Computes the minimum amongst two Arrays of a type T which implements the [Minimum] trait.
+/// Returns a [Result::Ok] containing the minimum value
+/// or an [Result::Err] containing the error, if no minimum value was found.
+///
+/// We deal with errors in underlying function with the [?] operator.
+///
+/// # Example
+///
+/// ```
+/// # use part07::find_minimum::{find_min_amongst_arrays_qm_op};
+/// # fn main() {
+/// let tab_a = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let tab_b = [22, 34, 11, 4, 52, 99, 71, 13, 43];
+/// let min = find_min_amongst_arrays_qm_op(&tab_a, &tab_b);
+/// assert!(min == Ok(2));
+/// # }
+/// ```
+///
+/// ```
+/// # use part07::find_minimum::{find_min_amongst_arrays_qm_op};
+/// # fn main() {
+/// let tab_a = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let tab_b : [i32; 0] = [];
+/// let min = find_min_amongst_arrays_qm_op(&tab_a, &tab_b);
+/// assert!(min.is_err());
+/// # }
+/// ```
+// ANCHOR: min_two_tabs_qm
+pub fn find_min_amongst_arrays_qm_op<T: Minimum>(lhs: &[T], rhs: &[T]) -> Result<T, FindMinError> {
+    // The question mark operator will unpack the value if the function returns [Result::Ok]
+    // or end the function and return the [Result:Err] to the caller.
+    let min_l = find_min_with_result(lhs)?;
+    let min_r = find_min_with_result(rhs)?;
+
+    Ok(min_l.min(min_r))
+}
+// ANCHOR_END: min_two_tabs_qm
diff --git a/codes/rust_lang/part07/src/io.rs b/codes/rust_lang/part07/src/io.rs
index 2eeaeb4f0201bac3b31daede9f1f2ffb2c0444d2..7a495499e8a65204e982f16093fabdf1cfb5251a 100644
--- a/codes/rust_lang/part07/src/io.rs
+++ b/codes/rust_lang/part07/src/io.rs
@@ -1,35 +1,23 @@
-use std::io::BufRead;
+//! Contains functions to interact with the user, either
+//! by reading inputs from the terminal, either by writing values
+//! in it.
 
-/// 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"));
-            }
-        };
+/// Poorly emulates the parsing of a command line.
+pub fn read_command_line_correct() -> [i32; 9] {
+    [10, 32, 12, 43, 52, 53, 83, 2, 9]
+}
 
-        match line.trim().parse::<i32>() {
-            Ok(num) => v.push(num),
-            Err(_) => {
-                return Err(String::from("Could not parse integer"));
-            }
-        }
-    }
-    Ok(v)
+/// Poorly emulates the parsing of a command line.
+pub fn read_empty_command_line() -> [i32; 0] {
+    []
 }
 
 /// Prints all the elements of the `tab`.
 /// Tab is borrowed here
-pub fn print_tab(tab: &Vec<i32>) {
+pub fn print_tab(tab: &[i32]) {
+    print!("[ ");
     for t in tab {
         print!("{} ", t);
     }
-    println!();
+    println!("]");
 }
diff --git a/codes/rust_lang/part07/src/lib.rs b/codes/rust_lang/part07/src/lib.rs
index dd53b82629e1b15c144969d81fc4e6c075d2e4ff..e6c7da45ca41ed5d6832544c8013993a0f65d1da 100644
--- a/codes/rust_lang/part07/src/lib.rs
+++ b/codes/rust_lang/part07/src/lib.rs
@@ -1,59 +1,87 @@
-/*!
-part07 illustrates the use of [Vec] and the Error Handling with [Option] and [Result].
-It also showcases struct enums.
-*/
+//! This crate shows us different ways of dealing with errors in a Rust program.
+//! You will find examples of [Option], [Result] and [panic!].
 
+pub mod find_minimum;
 pub mod io;
-mod minimum;
-pub mod something_or_nothing;
+pub mod minimum;
 
 #[cfg(test)]
 mod tests {
-    use crate::minimum::Minimum;
-    use crate::something_or_nothing::{find_min, SomethingOrNothing};
+    use crate::find_minimum::{
+        find_min_amongst_arrays_by_hand, find_min_amongst_arrays_qm_op, find_min_with_option,
+        find_min_with_panic, find_min_with_result,
+    };
+    const TAB: [i32; 9] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+    const TAB_B: [i32; 9] = [22, 34, 11, 4, 52, 99, 71, 13, 43];
+    const TAB_EMPTY: [i32; 0] = [];
+    const MIN_TAB: i32 = 2;
 
     #[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));
+    fn test_find_min_option() {
+        let min = find_min_with_option(&TAB);
+
+        assert!(min == Some(MIN_TAB));
+    }
+
+    #[test]
+    fn test_find_min_option_empty() {
+        let min = find_min_with_option(&TAB_EMPTY);
+
+        assert!(min.is_none());
+    }
+
+    #[test]
+    fn test_find_min_result() {
+        let min = find_min_with_result(&TAB);
+
+        assert!(min == Ok(MIN_TAB));
+    }
+
+    #[test]
+    fn test_find_min_result_empty() {
+        let min = find_min_with_result(&TAB_EMPTY);
+
+        assert!(min.is_err());
+    }
+
+    #[test]
+    fn test_find_min_panic() {
+        let min = find_min_with_panic(&TAB);
+
+        assert!(min == MIN_TAB);
     }
 
     #[test]
     #[should_panic]
-    fn test_failure_creation() {
-        let n2: SomethingOrNothing<i32> = SomethingOrNothing::new(1);
-        assert!(n2 == SomethingOrNothing::default());
-        assert!(n2 == SomethingOrNothing::new(2));
+    fn test_find_min_panic_empty() {
+        let _min = find_min_with_panic(&TAB_EMPTY);
+    }
+
+    #[test]
+    fn test_find_min_amongst_arrays_bh() {
+        let min = find_min_amongst_arrays_by_hand(&TAB, &TAB_B);
+
+        assert!(min == Ok(MIN_TAB));
     }
 
     #[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));
+    fn test_find_min_amongst_arrays_qm() {
+        let min = find_min_amongst_arrays_qm_op(&TAB, &TAB_B);
+
+        assert!(min == Ok(MIN_TAB));
     }
 
     #[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);
+    fn test_find_min_amongst_arrays_bh_empty() {
+        let min = find_min_amongst_arrays_by_hand(&TAB, &TAB_EMPTY);
+
+        assert!(min.is_err());
     }
 
     #[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);
+    fn test_find_min_amongst_arrays_qm_empty() {
+        let min = find_min_amongst_arrays_qm_op(&TAB, &TAB_EMPTY);
+
+        assert!(min.is_err());
     }
 }
diff --git a/codes/rust_lang/part07/src/main.rs b/codes/rust_lang/part07/src/main.rs
index 8ee8b45dded0909740a51df45e36af5ef513f0c8..a967099a3b0485ec23964110b9fb6b1ebc85faa4 100644
--- a/codes/rust_lang/part07/src/main.rs
+++ b/codes/rust_lang/part07/src/main.rs
@@ -1,14 +1,41 @@
+use part07::find_minimum::{
+    find_min_amongst_arrays_qm_op, find_min_with_option, find_min_with_result,
+    FindMinError::EmptyList, FindMinError::UnsupportedError,
+};
 use part07::io;
-use part07::something_or_nothing::find_min;
-
-fn main() -> Result<(), String> {
-    let tab = match io::read_command_line() {
-        Ok(tab) => tab,
-        Err(s) => return Err(s),
-    };
-    println!("Among the Somethings in the list:");
+
+fn main() {
+    let tab = io::read_command_line_correct();
+    println!("Among the elements in the list:");
+    io::print_tab(&tab);
+    let min = find_min_with_option(&tab);
+    match min {
+        Some(val) => print!("The minimum value is {}", val),
+        None => eprintln!("There is no minimum since the list is empty"),
+    }
+    println!("");
+    println!("");
+
+    let tab_empty = io::read_empty_command_line();
+    println!("Among the elements in the list:");
+    io::print_tab(&tab_empty);
+
+    //ANCHOR: parse_result
+    let min = find_min_with_result(&tab_empty);
+    match min {
+        Ok(val) => print!("The minimum value is {}", val),
+        Err(EmptyList) => eprintln!("The array is empty"),
+        Err(UnsupportedError(msg)) => panic!("Unsupported error : {}", msg),
+    }
+    //ANCHOR_END: parse_result
+
+    println!("Among the elements in the lists:");
     io::print_tab(&tab);
-    let min = find_min(&tab);
-    min.print();
-    Ok(())
+    io::print_tab(&tab_empty);
+    let min = find_min_amongst_arrays_qm_op(&tab, &tab_empty);
+    match min {
+        Ok(val) => print!("The minimum value is {}", val),
+        Err(EmptyList) => eprintln!("One or both arrays are empty"),
+        Err(UnsupportedError(msg)) => panic!("Unsupported error : {}", msg),
+    }
 }
diff --git a/codes/rust_lang/part07/src/minimum.rs b/codes/rust_lang/part07/src/minimum.rs
index 7d7a654b8f2c43bc76e35616813465c6142a0bff..222b12c33045f361977066521ff2b7206b0bed9c 100644
--- a/codes/rust_lang/part07/src/minimum.rs
+++ b/codes/rust_lang/part07/src/minimum.rs
@@ -1,5 +1,18 @@
-// If we remove Copy, we have a problem with the t in tab
-// in the computation of the minimum.
+//! Contains a generic trait implementation for computing the minimum between two
+//! values. It is the equivalent of the `<` operator.
+//!
+//! # Examples
+//!
+//! For integers this would look like
+//!
+//! ```
+//! # use part07::minimum::Minimum;
+//! let one = 1;
+//! let two = 2;
+//! assert!(Minimum::min(one, two) == one);
+//! ```
+
+/// The [Minimum] trait computes the minimum value between two values of a type
 pub trait Minimum: Copy {
     fn min(self, rhs: Self) -> Self;
 }
@@ -13,3 +26,35 @@ impl Minimum for i32 {
         }
     }
 }
+
+// ANCHOR: min_for_option
+impl<T: Minimum> Minimum for Option<T> {
+    fn min(self, rhs: Self) -> Self {
+        match self {
+            Some(val_l) => Some(match rhs {
+                Some(val_r) => val_l.min(val_r),
+                None => val_l,
+            }),
+            None => match rhs {
+                Some(val_r) => Some(val_r),
+                None => None,
+            },
+        }
+    }
+}
+// ANCHOR_END: min_for_option
+
+#[cfg(test)]
+mod tests {
+    use crate::minimum::Minimum;
+
+    #[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);
+    }
+}
diff --git a/codes/rust_lang/part07/src/something_or_nothing.rs b/codes/rust_lang/part07/src/something_or_nothing.rs
deleted file mode 100644
index 600bf0c6dbfbc567350a0ce74d4885bc4d07d054..0000000000000000000000000000000000000000
--- a/codes/rust_lang/part07/src/something_or_nothing.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-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 part07::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 part07::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> {
-    let mut minimum: SomethingOrNothing<T> = SomethingOrNothing(None);
-    // Here is T is Copyable. Which means that t is not moved in the loop
-    for t in tab {
-        minimum = minimum.min(SomethingOrNothing::new(*t));
-    }
-    minimum
-}