diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md
index 718d00bd83710e40deada98bb6803df45e8ca210..bbcd71961de0b9cc279a9c1664ed13d6e8ccd0de 100644
--- a/book/src/SUMMARY.md
+++ b/book/src/SUMMARY.md
@@ -14,5 +14,7 @@
 - [Part 09](./part09.md)
 - [Part 10](./part10.md)
 - [Part 11](./part11.md)
+- [Les collections](./collections.md)
+- [Lifetimes](./lifetimes.md)
 - [CLI](./cli.md)
 - [Part 12](./part12.md)
diff --git a/book/src/collections.md b/book/src/collections.md
new file mode 100644
index 0000000000000000000000000000000000000000..cd901fc2127dd34bc0dec7d50087dd56df41169e
--- /dev/null
+++ b/book/src/collections.md
@@ -0,0 +1,194 @@
+# Les collections
+
+## Concepts
+
+Les concepts abordés dans cet exemple sont:
+
+- [Les collections](#les-collections)
+  - [Concepts](#concepts)
+  - [Documentation](#documentation)
+  - [Discussion](#discussion)
+    - [Le type `Vec`](#le-type-vect)
+    - [Le type `String`](#le-type-string)
+    - [Les slices](#les-slices)
+
+## Documentation
+
+Afin de compléter ce cours, je vous recommande la lecture des ressources suivantes :
+
+- [Les Vec](https://doc.rust-lang.org/book/ch08-01-vectors.html)
+- [Les String](https://doc.rust-lang.org/book/ch08-02-strings.html)
+- [Les slices](https://doc.rust-lang.org/book/ch04-03-slices.html)
+
+## Discussion
+
+En Rust, comme dans la plupart des langages modernes, il existe des structures de données qui permettent
+de se simplifier la vie lors de l'implémentation de divers algorithmes.
+
+Dans ce chapitre, nous allons discuter des types `Vec<T>`, `String`, des slices.
+
+Dans ce code nous modifions que très peu le code [de la partie 6](part06.md) afin
+d'utiliser les types `Vec<i32>`, `String` et les slices.
+
+### Le type `Vec<T>`
+
+Le type `Vec<T>` est une collection qui permet de stocker des données d'un type unique générique, `T`.
+Ces données sont stockées dans un espace mémoire qui est garanti d'être contigu. Cet espace mémoire
+peut changer dynamiquement à l'exécution contrairement aux tableaux statiques. D'un certain point
+de vue, on peut le considérer comme un "pointeur intelligent": un `Vec` est un pointeur sur le tas,
+qui a une certaine capacité mémoire et sait combien la mémoire sur laquelle il pointe
+est pleine.
+
+Dans notre code, nous avons créé une fonction `read_command_line()`
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:read_command_line}}
+```
+Ici, un `Vec<i32>` est instancié et on ajoute des éléments aléatoires dedans à l'aide de la
+crate `rand()`.
+Pour créer un `Vec` vide, on utilise la fonction associée, qui crée un vecteur vide
+```rust
+{{#include ../../codes/rust_lang/collections/src/io.rs:vec_new}}
+```
+Ensuite, on remplit le vecteur avec des nombres aléatoires à l'aide
+d'une boucle `for` 
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:vec_for}}
+```
+qui itère sur les indices allant de `0` à `len-1`.
+Comme, nous n'utilisons pas l'indice, nous l'ignorons à l'aide de l'annotation `_i`.
+On ajoute des éléments dans le vecteur avec la fonction `push()` et comme nous modifions
+`v` il est primordial de noter qu'il est `mut`-able. Le générateur de nombre aléatoire
+est stocké dans une variable `rng` qui doit elle aussi être mutable.
+En effet, les générateurs de nombres aléatoires stockent en général un état interne.
+
+### Le type `String`
+
+Une `String` ou un chaîne de caractère, est une séquence de caractères `UTF-8`.
+On pourrait penser naïvement que ce n'est rien d'autre qu'un `Vec<char>`: en fait c'est plus compliqué que cela.
+Bien que la chaîne de caractères, soit également rien d'autre qu'un pointeur vers des données sur le tas,
+ainsi qu'une variable contenant la capacité de la mémoire sur laquelle pointe le pointeur et son remplissage.
+
+Le problème principal vient de l'encodage `UTF-8`: c'est un encodage de taille variable qui englobe les caractères
+ASCII (qui sont stockés sur un octet) et une très grande quantité d'autres caractères (l'alphabet grec, des emojis, etc.)
+qui sont stockés sur 1 à 4 octets. Ainsi chaque lettre de la chaîne de caractère correspond à un nombre variable d'octets
+(ce qui n'est pas le cas pour un `Vec`). Il est donc très vivement **déconseillé** de tenter d'indexer
+une `String` (faire `s[i]`) comme on le ferait avec un `Vec`. Il faut plutôt utiliser la méthode `.get(i)` qui
+interprète les caractères en fonction de la longueur de leurs encodages.
+
+Une illustration de l'utilisation d'une chaîne de caractère se trouve à la fonction
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:read_command_line_str}}
+```
+Cette fonction construit une chaîne de caractères constituées de nombres et d'espaces,
+puis la transforme en `Vec<i32>` dont on calculera ensuite le minimum.
+
+Une `String` est souvent construite à partir d'une "chaîne littérale" à l'aide du trait de conversion `From`
+(on les reconnaît parce qu'elles sont entourées de guillemets,  `""`)
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:from}}
+```
+dont le type est `str` formellement (c'est une chaîne de caractères qui vit durant toute la durée de vie du programme).
+Néanmoins, le type `str` n'est jamais utilisé en tant que tel en Rust, mais on utilise plutôt son "slice"
+`&str` (plus sur les "tranches" dans la [section suivante](#les-slices)). 
+
+Nous voyons que dans le code ci-dessus nous avons déclaré la variable `s` comme étant mutable, car ensuite nous ajoutons
+une slice de chaîne de caractère (de type `&str`) à l'aide de la fonction `push_str()`
+dans `s`
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:push_str}}
+```
+On peut également ajouter des `char` (ils sont entourés d'apostrophes `' '`) à l'aide de la fonction `push()`
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:push_char}}
+```
+Ensuite cette chaîne de caractères est convertie en `Vec<&str>` où chaque élément du `Vec` est un mot, qui est une sous chaîne de `s`.
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:split}}
+```
+Finalement, dans 
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:string_for}}
+```
+on crée un nouveau `Vec<i32>` dans lequel on ajoute les mots convertis en entiers.
+On commence par itérer sur le `Vec<&str>` en utilisant les indices de `0` à `s.len()-1` (la longueur du `Vec` `s`).
+Puis nous passons à la conversion à proprement parler, bien qu'on fasse des choses un peu compliquées
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:conversion}}
+```
+Ici, on commence par récupérer le `i`-ème index de `s` à l'aide de la méthode `get(i)` qui retourne
+une `Option<&str>` (si `i` est un indice valide nous avons `Some(s[i])`, sinon `None`). Puis, nous transformons
+l'option avec `ok_or()` (nous encapsulons `s[i]` dans un `Ok()` si nous avons un `Some()` et transformons 
+`None`en `Err("Unable to index")`). Ensuite nous "parsons" `s[i]` et retournons une erreur si le parsing échoue.
+Si tout s'est bien passé nous faisons donc un `push()` de chaque `i32` et finissons par retourner le `Vec<i32>`
+encapsulé dans un `Ok()`.
+
+### Les slices
+
+Un slice est une "tranche" de tableau, statique ou dynamique: une référence vers un bout de mémoire et
+la longueur de cette mémoire.
+
+Ainsi, si nous créons un tableau statique, nous pouvons référencer une "tranche" ou slice
+avec la syntaxe suivante
+```rust
+let a = [1, 2, 3, 4, 5, 6, 7, 8];
+let b = &a[1..4]; // on pointe vers [2, 3, 4]
+```
+`b` sera donc une référence et saura que la mémoire sur laquelle elle pointe est de longueur `3`
+(cette information permet d'éviter les dépassements de capacité).
+On notera la syntaxe `x..y` où `y` est non inclus (comme pour la boucle `for` avec les indices).
+Il existe également une syntaxe sans bornes à gauche, à droite, ou à gauche et à droite.
+```rust
+let a = [1, 2, 3, 4, 5, 6, 7, 8];
+let b = &a[1..]; // on pointe vers [2, 3, .., 8]
+let b = &a[..5]; // on pointe vers [1, 2, .., 5]
+let b = &a[..]; // on pointe vers [1, 2, .., 8]
+```
+Cette syntaxe s'applique également pour toute collection qu'on peut indexer
+Le type d'un slice est noté par `&[T]`, où `T` est un type. On en voit un exemple
+lorsqu'on veut afficher un tableau par exemple
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/io.rs:print_tab}}
+```
+ou encore dans la fonction `find_min()`
+```rust,ignore
+{{#include ../../codes/rust_lang/collections/src/something_or_nothing.rs:find_min}}
+```
+Comme on le voit dans le `main()` l'implémentation à l'aide d'un slice dans les fonction
+permet une bien plus grande généricité que si on impose un type `Vec`, un tableau statique,
+ou un slice.
+```rust,ignore
+// Vec
+{{#include ../../codes/rust_lang/collections/src/main.rs:vec}}
+// Slice
+{{#include ../../codes/rust_lang/collections/src/main.rs:ref}}
+// Array
+{{#include ../../codes/rust_lang/collections/src/main.rs:tab}}
+```
+
+La notation `&str` représente ainsi une référence vers un `str` qui est une chaîne de caractères
+littérale, allouée pour la durée entière d'un programme dans une zone dédiée de la mémoire.
+Le type `str` étant "immovable" il n'est jamais utilisé tel quel, mais uniquement via des références.
+
+Comme pour le slice utilisé pour généraliser le passage en argument des tableaux,
+le slice de string `&str` est également utilisé pour généraliser le passage de argument
+de chaînes de caractères.
+
+## Rustlings
+
+Les rustlings à faire dans ce chapitre sont les suivants:
+
+### Les `Vec`
+
+```bash
+$ rustlings run vecs1
+$ rustlings run vecs2
+```
+
+### Les `String`
+
+```bash
+$ rustlings run strings1
+$ rustlings run strings2
+$ rustlings run strings3
+$ rustlings run strings4
+```
diff --git a/book/src/lifetimes.md b/book/src/lifetimes.md
new file mode 100644
index 0000000000000000000000000000000000000000..7254b095f5bbff0e8cd0bdf87c0ae36ab28d740d
--- /dev/null
+++ b/book/src/lifetimes.md
@@ -0,0 +1,261 @@
+# Lifetimes
+
+## Concepts
+
+Les concepts abordés dans cet exemple sont:
+
+1. [Le pattern `NewYtpe`](#le-pattern-newtype)
+2. [Les lifetimes](#les-lifetimes)
+3. [Les itérateurs et la généricité]()
+
+Pour plus d'informations sur le pattern `NewType`, vous pouvez vous référer aux
+chapitres [19.2](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#using-the-newtype-pattern-to-implement-external-traits-on-external-types) et [19.3](https://doc.rust-lang.org/book/ch19-04-advanced-types.html) du livre.
+Pour les lifetimes, il y a le [chapitre du livre](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html) correspondant,
+ainsi que celui du [Rustonomicon](https://doc.rust-lang.org/nomicon/lifetimes.html).
+
+## Discussion
+
+Dans ce chapitre, nous allons voir principalement deux concepts différents qui sont importants en Rust
+et qu'on retrouve dans beaucoup de code. Les lifetimes, en particulier, sont un sujet complexe
+et on verra deux applications différentes mais cela constitue la pointe de l'iceberg des applications
+possibles. Le pattern `NewType` est lui bien plus simple, et ne nécessite pas une très longue discussion.
+
+### Le pattern `NewType`
+
+Le pattern `NewType` très commun en Rust consiste à encapsuler un type externe à une crate, dans un type local
+comme dans
+```rust
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:newtype}}
+```
+où on encapsule le type externe `Option<T>` dans `SomethingOrNothing<T>`.
+Ce type a un paramètre générique `T` et dérive le trait `Debug` qui permet
+de faire un affichage détaillé (mais pas très joli) du contenu du type.
+Ce pattern est nécessaire pour [implémenter un trait externe sur un type extern](https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#using-the-newtype-pattern-to-implement-external-traits-on-external-types) (ce qui est interdit en Rust). Ainsi, il ne nous aurait pas été possible d'implémenter
+le trait `Display` (qui permet d'afficher une instance du type), `Default` (qui 
+permet de créer une instance par défaut), ou `PartialEq` (qui permet de vérifier 
+l'égalité de deux instance du type) directement pour le type `Option<T>`, car 
+`Display`, `Default`, et `PartialEq` sont des traits externes tout comme le type 
+`Option<T>`. Pour des types externes l'implémentation de traits externes
+est interdite (c'est la *orphan rule*). Cela interdit de "casser" un code externe
+en autorisant de multiples implémentations du même trait pour le même type.
+Ainsi `SomethingOrNothing<T>` nous permet d'implémenter ces trois traits
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:newtype_display}}
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:newtype_default}}
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:newtype_partialeq}}
+```
+Nous aimerions attirer votre attention sur une particularité du *pattern matching*
+ici. On voit que nous pouvons faire un match sur des types *imbriqués*
+comme pour `SomethingOrNothing(Some(val))`, on va déstructurer les types énumérés
+jusqu'à obtenir `val` qui est la valeur qui nous intéresse.
+
+Une deuxième utilité du pattern NewType est qu'elle permet de limiter
+les fonctionnalités d'un type car cela nécessite de réimplémenter
+les méthodes qui lui sont propres. Dans notre cas, seule la méthode `unwrap()`
+de `Option<T>` nous intéresse (cette fonction retourne la valeur encapsulée dans
+la variante `Some()` ou panique si on a un `None`). Ainsi, on n'implémente
+que celle-là
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:newtype_unwrap}}
+```
+On peut noter qu'on a à faire à une `struct` avec des membres anonymes.
+Ainsi, les membres peuvent être accédés comme pour les tuples et comme il n'y
+en a qu'un dans un `SomethingOrNothing<T>`, on y accède avec le sélecteur `self.0`.
+
+### Les lifetimes
+
+Dans cette section nous discutons l'utilisation de l'annotation des lifetimes
+dans différents cas: les structures, les méthodes, les traits, et les fonctions.
+
+#### Les structures
+
+Dans notre programme, nous utiliserons le type `CustomInt` qui est une représentation d'un entier
+qui peut avoir une taille arbitraire (dans les limites de la mémoire de la machine).
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/custom_int.rs:custom_int}}
+```
+Un tel entier est représenté par un signe `i8` (qui peut valoir `+1` ou `-1`), et un 
+`Vec<u8>`, un tableau dynamique de `u8` (les valeurs admissibles vont de `0` à `9`), 
+qui contient les chiffres du nombre stockés de droite à gauche: `[7,3,3,1]`
+est le nombre `1337`.
+
+Ces nombres pouvant être gigantesques, nous voulons éviter de les dupliquer lorsque nous
+les copions ou les manipulons. Une solution est de stocker uniquement
+une référence vers les données, c'est-à-dire que `data` est de type `&Vec<u8>`. 
+On voit dans le code ci-dessus, qu'il est nécessaire d'annoter la durée de vie
+de la référence avec `'a`. Si on omet l'annotation de durée de vie le
+compilateur nous préviendra et nous oblige à en spécifier un
+```console
+error[E0106]: missing lifetime specifier
+  --> src/custom_int.rs:13:11
+   |
+13 |     data: &Vec<u8>,
+   |           ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+9  ~ pub struct CustomInt<'a> {
+10 |     /// The data contains the unsigned integers that are read from right to left
+11 |     /// The number 1337 is stored as vec![7, 3, 3, 1]. Each number must be in the range [0,9]
+12 |     /// and no trailing 0s are allowed.
+13 ~     data: &'a Vec<u8>,
+```
+Il est en effet impossible pour le compilateur de savoir si la référence vivra
+assez longtemps pour vivre plus longtemps qu'une instance de `CustomInt`.
+
+#### Les méthodes
+
+L'implémentation des méthodes requiert une annotation sous peine d'erreurs
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/custom_int.rs:custom_int_impl}}
+```
+Il en va de même avec la fonction associée, `try_new()`
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/custom_int.rs:try_new}}
+```
+qui nécessite
+une annotation dans la définition du type de `data`. En effet, l'annotation
+permet de dire au compilateur que `data`, l'argument de `try_new()`, vit suffisamment
+longtemps pour permettre la création d'une instance de `CustomInt`.
+
+#### Les traits
+
+Il y a plusieurs traits qui sont implémentés pour `CustomInt<'a>`.: `PartialEq`, `Display`, et `Minumum`. Pour `PartialEq` et `Display`, il suffit de renseigner
+l'annotation `'a` à l'instruction `impl` comme pour un paramètre générique, voir
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/custom_int.rs:partialeq}}
+{{#include ../../codes/rust_lang/lifetimes/src/custom_int.rs:display}}
+```
+Il est possible d'écrire la même chose, en omettant l'annotation `'a`
+et en la remplaçant par `'_` pour simplifier la notation
+```rust,ignore
+impl PartialEq for CustomInt<'_>
+```
+Comme l'annotation n'est utilisée nulle par, Rust offre ce sucre syntaxique
+pour éviter d'écrire trop d'annotations.
+
+Pour le trait `Minimum` les choses se compliquent un peu.
+Pour éviter le copies/clones, on a fait le choix de 
+n'utiliser que des références dans les arguments, comme dans le type de retour
+du calcul du minimum de deux valeurs
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/minimum.rs:minimum}}
+```
+Ainsi, comme il y deux références en argument et une référence en sortie,
+il est nécessaire d'annoter les références, car sinon le compilateur ne sait pas
+avec que durée de vie annoter la sortie (les 2 sont possibles). Ainsi nous annotons
+le trait avec la durée de vie `'a`, puis cette durée de vie est utilisée pour toutes
+les références dans la fonction `min()`. Ainsi toutes les références ont la même 
+durée de vie que celle annotée dans le trait.
+
+Il y a trois implémentation de ce trait: la première est pour les `i32`, la seconde pour `SomthingOrNothing<T>`, et finalement pour `CustomInt`. 
+
+1. Pour l'implémentation
+pour les `i32`
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/minimum.rs:min}}
+```
+l'implémentation est triviale, il y a uniquement besoin de reprendre
+l'annotation pour l'implémentation dans les références en argument
+de la fonction et dans le retour de la fonction. En effet, comme les
+deux arguments peuvent être retournés, il est nécessaire de préciser
+au compilateur que la durée de vie sera la même, sinon il met automatiquement
+une durée de vie à chaque argument et reprend celle à `&self` comme la durée
+de vie de la sortie. En d'autres termes, sans annotations, on aurait
+```rust,ignore
+fn min(&self, rhs: &Self) -> &Self
+```
+qui serait converti automatiquement par le compilateur en
+```rust,ignore
+fn min(&'a self, rhs: &'b Self) -> &'a Self {
+    if self < rhs {
+        self
+    } else {
+        rhs
+    }
+}
+```
+et la durée de vie `'a` du retour est pas compatible avec la durée de vie
+qui serait retournée au moment de retourner `rhs` (qui est `'b`). Ce qui entraînerait une erreur de compilation (on aime pas ça les erreurs nous).
+2. Pour l'implémentation pour `SomethingOrNothing<T>`, nous avons un paramètre générique. 
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:min}}
+```
+Ainsi nous constatons, que la ligne correspondant à la déclaration
+de l'implémentation du trait `Minimum` nécessite la déclaration de la durée de vie `'a`, ainsi que du type générique `T`. On voit dans l'implémentation
+de la fonction `min()`, que nous faisons appel à `min()` sur le type `T`,
+et que donc celui-ci doit implémenter le trait `Minimum` (tout comme le trait `PartialEq`).
+On doit ainsi répercuter la durée de vie sur tous les `Minimum` présents sur la ligne `impl`
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:impl_min}}
+```
+Nous ne discutons pas l'implémentation à proprement parler qui est assez raisonnable
+pour trouver le minimum de deux valeur encapsulées dans un `NewType`.
+3. Finalement, on a l'implémentation pour `CustomInt` qui n'a rien de vraiment nouveau
+par rapport aux implémentation précédentes (on réutilise l'annotation `'a` dans `min()` directement), à part la complexité monumentale de la fonction (elle fait plein de lignes)
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/custom_int.rs:min}}
+```
+En effet, on doit faire attention au signe, à la longueur de notre `CustomInt` et
+à plusieurs autres joyeusetés. Ici, on peut utiliser le trait `Ord` 
+(la fonction `cmp()`) pour faire les comparaisons entre le signe et les digits de
+nos nombres. Le trait `Ord` représente les opérateurs `<, >, =, <=, >=`, via la fonction `cmp()` qui retourne trois types correspondants
+```rust,ignore
+Ordering::Less
+Ordering::Greater
+Ordering::Equal
+```
+L'utilisation
+d'un type énuméré pour gérer chacun des cas peut sembler verbeux et complexe. Cependant,
+il permet de garantir à la *compilation* qu'on a pas oublié de traiter un cas par accident. Et ça, ça n'a pas de prix.
+
+#### Les fonctions
+
+Finalement, on utilise les lifetimes dans une fonction qui permet
+le calcul du minimum dans un tableau et retourne un `SomethingOrNothing<&T>` contenant une référence vers l'élément le plus petit.
+
+Cette fonction est générique avec le paramètre `T` et prend en argument une référence qui doivent être annotée.
+
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:find_min}}
+```
+La fonction `find_min()` prend en argument un *slice* de type générique `T` qui doit implémenter `Minimum`. Comme le type de retour est `SomethingOrNothing<&T>`, donc on
+encapsule une référence vers la valeur minimale, il est nécessaire d'annoter
+les durées de vies car sinon elles auraient deux valeur différentes ce qui poserait problème au compilateur (car elles doivent être les mêmes).
+
+L'implémentation de cette fonction, n'est pas très complexe, mais est très intéressante. En premier lieu, pour des question de généricité de l'implémentation
+nous passons en argument un *slice* de `T`: cette façon de procéder permet
+d'avoir un argument qui serait une référence vers un tableau statique ou vers un `Vec<T>` sans changer l'implémentation. De plus, nous utilisons ici un itérateur
+sur le tableau est faisons un `fold()` sur cet itérateur. Le `fold()` prend en argument
+un élément neutre (quel est la valeur initiale stockée dans le `fold()`). Ici c'est
+```rust,ignore
+SomethingOrNothing::default()
+```
+puis une fonction anonyme prenant deux arguments
+```rust,ignore
+|res, x| {}
+```
+où la valeur retournée par cette fonction écrase la valeur de `res` à chaque `next()`
+de l'itérateur et qui doit avoir le même type que l'élément neutre, et où `x` est la valeur courante de l'itérateur. Ici, le type de `res` est `SomethingOrNothing<&T>` et
+le type de `x` est `&T`. La fonction anonyme
+```rust,ignore
+let r = match res {
+    SomethingOrNothing(None) => x,
+    SomethingOrNothing(Some(r)) => r.min(x),
+};
+SomethingOrNothing::new(r)
+```
+calcule le minimum entre la valeur actuelle stockée dans `res` et `x` en utilisant
+la fonction `min()` ce qui implique que `T` doit implémenter `Minimum`.
+
+### En pratique
+
+Dans la fonction `main()` de notre programme
+```rust,ignore
+{{#include ../../codes/rust_lang/lifetimes/src/something_or_nothing.rs:find_min}}
+```
+on crée un tableau de `CustomInt` qui sont créés à partir de références
+sur les tableau `v1`, `v2`, etc. qui vivrons ainsi jusqu'à la fin de notre
+programme et qui seront promenées sans qu'on ait besoin de les copier à aucun moment.
+Les liens entre les durées de vie des références que nous nous sommes efforcés d'annoter dan tout au long ce code sont vérifiées par le compilateur qui
+vérifie qu'elles sont toutes valides à la compilation.
\ No newline at end of file
diff --git a/codes/rust_lang/collections/Cargo.toml b/codes/rust_lang/collections/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..50a0d49c74afd47cb41267f168a32f4e80c1b20e
--- /dev/null
+++ b/codes/rust_lang/collections/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "collections"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+rand = "0.8.5"
\ No newline at end of file
diff --git a/codes/rust_lang/collections/src/io.rs b/codes/rust_lang/collections/src/io.rs
new file mode 100644
index 0000000000000000000000000000000000000000..cf0f45476dd09bc12fbbf4a22843e293f86c6ae4
--- /dev/null
+++ b/codes/rust_lang/collections/src/io.rs
@@ -0,0 +1,68 @@
+//! Contains functions to interact with the user, either
+//! by reading inputs from the terminal, either by writing values
+//! in it.
+use rand::Rng;
+
+// ANCHOR: read_command_line
+/// Poorly emulates the parsing of a command line.
+pub fn read_command_line(len: usize) -> Vec<i32> {
+    let mut rng = rand::thread_rng();
+    // ANCHOR: vec_new
+    let mut v: Vec<i32> = Vec::new();
+    // ANCHOR_END: vec_new
+    // ANCHOR: vec_for
+    for _i in 0..len {
+        // ANCHOR: vec_push
+        v.push(rng.gen());
+        // ANCHOR: vec_push
+    }
+    // ANCHOR_END: vec_for
+    v
+}
+// ANCHOR_END: read_command_line
+
+// ANCHOR: read_command_line_str
+/// Poorly emulates the parsing of a command line.
+pub fn read_command_line_str() -> Result<Vec<i32>, String> {
+    // ANCHOR: from
+    let mut s = String::from("20 10 48 58 29 0 58 -10 39 5485 394");
+    // ANCHOR_END: from
+    // ANCHOR: push_str
+    s.push_str(" -100");
+    // ANCHOR_END: push_str
+    // ANCHOR: push_char
+    s.push(' ');
+    s.push('1');
+    s.push('2');
+    // ANCHOR_END: push_char
+    // ANCHOR: split
+    let s: Vec<&str> = s.split_ascii_whitespace().collect();
+    // ANCHOR_END: split
+
+    // ANCHOR: string_for
+    let mut v = Vec::new();
+    for i in 0..s.len() {
+        v.push(
+            // ANCHOR: conversion
+            s.get(i)
+                .ok_or(String::from("Unable to index"))?
+                .parse()
+                .map_err(|_| format!("Unable to parse {}", s[i]))?,
+            // ANCHOR_END: conversion
+        );
+    }
+    // ANCHOR_END: string_for
+    Ok(v)
+}
+// ANCHOR_END: read_command_line_str
+
+/// Prints all the elements of the `tab`.
+/// Tab is borrowed here
+// ANCHOR: print_tab
+pub fn print_tab(tab: &[i32]) {
+    for t in tab {
+        print!("{} ", t);
+    }
+    println!();
+}
+// ANCHOR_END: print_tab
diff --git a/codes/rust_lang/collections/src/lib.rs b/codes/rust_lang/collections/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0b02fce36d04c0f048032fd5600d5df3ea7be30d
--- /dev/null
+++ b/codes/rust_lang/collections/src/lib.rs
@@ -0,0 +1,80 @@
+//! This is an example of Rust crate comments (or inner comments).
+//! They will be rendered in the front page of your (crate) library.
+//!
+//! # How to generate the documentation
+//!
+//! In this program we wrote an algorithm that computes the minimum of
+//! a sequence of integers.
+//!
+//! To create the documentation run the command
+//! ```bash
+//! cargo doc
+//! ```
+//! The obtain documentation can be found in the `target/doc/collections/index.html` directory
+//!
+//! To view the documentation type
+//! ```bash
+//! cargo doc --open
+//! ```
+//! which will open the browser and show you the documentation.
+//!
+//! The documentation supports the CommonMarkdown syntax.
+//!
+//! Below we will use the `///` comments that will comment the code directly below.
+//! We can also sue `//` but they will not be rendered.
+//! All the lines written here could be enclosed in `/*! ... */` instead of being prefixed by `//!`.
+//!
+//! For more informations about writing documentation [follow that link](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html).
+//!
+//! # Tooling
+//!
+//! Also Rust comes with great tooling.
+//! - [Clippy](https://doc.rust-lang.org/stable/clippy/): The officiel Rust linter.
+//! - [Rustfmt](https://github.com/rust-lang/rustfmt): The official Rust code formatter.
+
+pub mod io;
+pub mod minimum;
+pub mod something_or_nothing;
+
+#[test]
+fn test_creation() {
+    use something_or_nothing::SomethingOrNothing;
+
+    let n1: SomethingOrNothing<i32> = SomethingOrNothing::default();
+    assert!(n1 == SomethingOrNothing::Nothing);
+    let n2: SomethingOrNothing<i32> = SomethingOrNothing::Something(1);
+    assert!(n2 == SomethingOrNothing::Something(1));
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::minimum::Minimum;
+    use crate::something_or_nothing::{find_min, SomethingOrNothing};
+
+    #[test]
+    #[should_panic]
+    fn test_failure_creation() {
+        let n2: SomethingOrNothing<i32> = SomethingOrNothing::Something(1);
+        assert!(n2 == SomethingOrNothing::Nothing);
+        assert!(n2 == SomethingOrNothing::Something(2));
+    }
+
+    #[test]
+    fn test_min() {
+        let a = [1, 5, -1, 2, 0, 10, 11, 0, 3];
+        let min = find_min(&a);
+        assert!(min == SomethingOrNothing::Something(-1));
+    }
+
+    #[test]
+    fn test_min_something_or_nothing() {
+        let x = SomethingOrNothing::Something(5i32);
+        let y = SomethingOrNothing::Something(10i32);
+        let z = SomethingOrNothing::Nothing;
+        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/collections/src/main.rs b/codes/rust_lang/collections/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..9f9263a1e5a55d0d5daece7dcdec9159f0d9da5a
--- /dev/null
+++ b/codes/rust_lang/collections/src/main.rs
@@ -0,0 +1,35 @@
+use collections::io;
+use collections::something_or_nothing::find_min;
+
+fn main() -> Result<(), String> {
+    //ANCHOR: vec
+    let tab: Vec<i32> = io::read_command_line(10usize);
+    println!("Among the Somethings in the list:");
+    io::print_tab(&tab);
+    let min = find_min(&tab);
+    min.print();
+    //ANCHOR_END: vec
+
+    let tab = io::read_command_line_str()?;
+    println!("Among the Somethings in the list:");
+    io::print_tab(&tab);
+    let min = find_min(&tab);
+    min.print();
+
+    //ANCHOR: ref
+    println!("Among the Somethings in the list:");
+    io::print_tab(&tab[1..9]);
+    let min = find_min(&tab[1..9]);
+    min.print();
+    //ANCHOR_END: ref
+
+    //ANCHOR: tab
+    let tab = [1, 2, 3, 4, 5, 6];
+    println!("Among the Somethings in the list:");
+    io::print_tab(&tab);
+    let min = find_min(&tab);
+    min.print();
+    //ANCHOR_END: tab
+
+    Ok(())
+}
diff --git a/codes/rust_lang/collections/src/minimum.rs b/codes/rust_lang/collections/src/minimum.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a4233159e669e7e910ccf23634b47f599e4d583c
--- /dev/null
+++ b/codes/rust_lang/collections/src/minimum.rs
@@ -0,0 +1,43 @@
+//! 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 collections::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;
+}
+
+impl Minimum for i32 {
+    fn min(self, rhs: Self) -> Self {
+        if self < rhs {
+            self
+        } else {
+            rhs
+        }
+    }
+}
+
+#[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/collections/src/something_or_nothing.rs b/codes/rust_lang/collections/src/something_or_nothing.rs
new file mode 100644
index 0000000000000000000000000000000000000000..92fbd9423024d176aa6e9d0f8cc7f11705465135
--- /dev/null
+++ b/codes/rust_lang/collections/src/something_or_nothing.rs
@@ -0,0 +1,104 @@
+//! Contains the core logic of the library, allowing to tore generic values
+//! (or their absence) and manipulate them.
+
+use crate::minimum::Minimum;
+
+/// An generic enumerated type that has two variants.
+///
+/// - Nothing
+/// - Something
+#[derive(Clone, Copy)]
+pub enum SomethingOrNothing<T> {
+    /// A [SomethingOrNothing::Nothing]
+    Nothing,
+    /// A [SomethingOrNothing::Something] encapsulating a T
+    Something(T),
+}
+
+impl<T: std::fmt::Display> SomethingOrNothing<T> {
+    /// A static function that prints the content of a SomethingOrNothing.
+    pub fn print(&self) {
+        match self {
+            SomethingOrNothing::Nothing => println!("Nothing."),
+            SomethingOrNothing::Something(val) => println!("Something is: {}", val),
+        }
+    }
+}
+
+/// Implementation of the [Default] trait that creates a [SomethingOrNothing]
+/// that is a `Nothing` variant.
+///
+/// # Example
+///
+/// ```
+/// # use collections::something_or_nothing::SomethingOrNothing;
+/// # fn main() {
+/// let def: SomethingOrNothing<i32> = SomethingOrNothing::default();
+/// assert!(def == SomethingOrNothing::Nothing);
+/// # }
+/// ```
+impl<T> Default for SomethingOrNothing<T> {
+    /// By Default a [SomethingOrNothing] is a nothing.
+    fn default() -> Self {
+        SomethingOrNothing::Nothing
+    }
+}
+
+/// Implementation of the [PartialEq] trait that is useful for tests.
+impl<T: PartialEq> PartialEq for SomethingOrNothing<T> {
+    fn eq(&self, other: &Self) -> bool {
+        match (self, other) {
+            (SomethingOrNothing::Nothing, SomethingOrNothing::Nothing) => true,
+            (SomethingOrNothing::Something(lhs), SomethingOrNothing::Something(rhs)) => {
+                *lhs == *rhs
+            }
+            _ => false,
+        }
+    }
+}
+
+/// Implementation of the [Minimum] trait used for comparing values
+/// in this crate.
+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)
+            }
+        }
+    }
+}
+
+/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
+/// Returns a [SomethingOrNothing::Something] containing the the minimum value
+/// or [SomethingOrNothing::Nothing] if no minimum value was found.
+///
+/// # Example
+///
+/// ```
+/// # use collections::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::Something(2));
+/// # }
+/// ```
+// ANCHOR: find_min
+pub fn find_min<T: Minimum>(tab: &[T]) -> SomethingOrNothing<T> {
+    let mut minimum = SomethingOrNothing::Nothing;
+    // Here is T is Copyable. Which means that t is not moved in the loop
+    for t in tab {
+        minimum = minimum.min(SomethingOrNothing::Something(*t));
+    }
+    minimum
+}
+// ANCHOR_END: find_min
diff --git a/codes/rust_lang/lifetimes/Cargo.toml b/codes/rust_lang/lifetimes/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..bc3f2629be97e53631ee5186294757a3e8844c1d
--- /dev/null
+++ b/codes/rust_lang/lifetimes/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "lifetimes"
+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/lifetimes/src/custom_int.rs b/codes/rust_lang/lifetimes/src/custom_int.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2a4c97e9a4f5214e06d072bc0d755f5d5e3f564d
--- /dev/null
+++ b/codes/rust_lang/lifetimes/src/custom_int.rs
@@ -0,0 +1,198 @@
+use std::cmp::Ordering;
+
+use crate::minimum::Minimum;
+
+/// Larger ints based on a [Vec] of [u8] to repensent arbitrary lengthy numbers.
+/// The number has a sign as well.
+// ANCHOR: custom_int
+#[derive(Debug)]
+pub struct CustomInt<'a> {
+    /// 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: &'a Vec<u8>,
+    /// Contains the sign of the number +/-1;
+    sign: i8,
+}
+// ANCHOR_END: custom_int
+
+// ANCHOR: custom_int_impl
+impl<'a> CustomInt<'a>
+// ANCHOR_END: custom_int_impl
+{
+    /// Tries to create a new [CustomInt]. If the number is valid it returns
+    /// an Ok(CustomInt) an Error otherwise.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use lifetimes::custom_int::CustomInt;
+    /// let v1 = vec![1, 2, 3, 4];
+    /// let num = CustomInt::try_new(&v1, 1);
+    /// assert!(num.is_ok());
+    /// let num = CustomInt::try_new(&v1, -1);
+    /// assert!(num.is_ok());
+    /// let num = CustomInt::try_new(&v1, 10);
+    /// assert!(num.is_err());
+    /// let num = CustomInt::try_new(&v1, -10);
+    /// assert!(num.is_err());
+    /// let v1 = vec![];
+    /// let num = CustomInt::try_new(&v1, -1);
+    /// assert!(num.is_err());
+    /// ```
+    ///
+    // ANCHOR: try_new
+    pub fn try_new(data: &'a Vec<u8>, sign: i8) -> Result<Self, String> {
+        if data.is_empty() {
+            Err(String::from("Data is empty."))
+        } else if sign == 1 || sign == -1 {
+            Ok(CustomInt { data, sign })
+        } else {
+            Err(String::from("Invalid sign."))
+        }
+    }
+    // ANCHOR_END: try_new
+}
+
+// ANCHOR: minimum
+impl<'a> Minimum<'a> for CustomInt<'a>
+// ANCHOR_END: minimum
+{
+    // ANCHOR: min
+    fn min(&'a self, rhs: &'a Self) -> &'a Self {
+        match self.sign.cmp(&rhs.sign) {
+            Ordering::Less => return self,
+            Ordering::Greater => return rhs,
+            Ordering::Equal => match self.data.len().cmp(&rhs.data.len()) {
+                Ordering::Less => {
+                    if self.sign == 1 {
+                        return self;
+                    } else {
+                        return rhs;
+                    }
+                }
+                Ordering::Greater => {
+                    if self.sign == 1 {
+                        return rhs;
+                    } else {
+                        return self;
+                    }
+                }
+                Ordering::Equal => {
+                    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;
+                        match ls.cmp(&rs) {
+                            Ordering::Less => return self,
+                            Ordering::Greater => return rhs,
+                            Ordering::Equal => {}
+                        }
+                    }
+                }
+            },
+        }
+        self
+    }
+    // ANCHOR_END: min
+}
+
+// ANCHOR: partialeq
+impl<'a> PartialEq for CustomInt<'a>
+// ANCHOR_END: partialeq
+{
+    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
+        }
+    }
+}
+
+// ANCHOR: display
+impl<'a> std::fmt::Display for CustomInt<'a>
+// ANCHOR_END: display
+{
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        // This could be replaced by an `?`
+        if self.sign == -1 {
+            write!(f, "-")?;
+        }
+
+        // This could be replaced by an `?`
+        let res = self
+            .data
+            .iter()
+            .rev()
+            .try_fold((), |_, t| write!(f, "{}", t));
+        res
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::custom_int::CustomInt;
+    use crate::minimum::Minimum;
+    use crate::something_or_nothing::find_min;
+
+    #[test]
+    fn test_creation() {
+        let v1 = vec![1, 2, 3, 4];
+        CustomInt::try_new(&v1, 1).unwrap();
+        CustomInt::try_new(&v1, -1).unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_failure_creation_sign() {
+        let v1 = vec![1, 2, 3, 4];
+        CustomInt::try_new(&v1, 10).unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_failure_creation_sign2() {
+        let v1 = vec![1, 2, 3, 4];
+        CustomInt::try_new(&v1, 0).unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_failure_creation_data() {
+        let v1 = vec![];
+        CustomInt::try_new(&v1, 1).unwrap();
+    }
+
+    #[test]
+    fn test_min() {
+        let mut v = Vec::new();
+        let v1 = vec![1, 2, 3, 4];
+        let v2 = vec![1, 2, 3];
+        let lhs = CustomInt::try_new(&v1, 1).unwrap();
+        let rhs = CustomInt::try_new(&v2, 1).unwrap();
+        assert!(rhs == *lhs.min(&rhs));
+        v.push(lhs);
+        v.push(rhs);
+        let lhs = CustomInt::try_new(&v1, -1).unwrap();
+        let rhs = CustomInt::try_new(&v2, -1).unwrap();
+        assert!(lhs == *lhs.min(&rhs));
+        v.push(lhs);
+        v.push(rhs);
+        let v1 = vec![1, 2, 3, 4];
+        let v2 = vec![1, 2, 5, 4];
+        let lhs = CustomInt::try_new(&v1, -1).unwrap();
+        let rhs = CustomInt::try_new(&v2, -1).unwrap();
+        assert!(rhs == *lhs.min(&rhs));
+        v.push(lhs);
+        v.push(rhs);
+        let lhs = CustomInt::try_new(&v1, 1).unwrap();
+        let rhs = CustomInt::try_new(&v2, 1).unwrap();
+        assert!(lhs == *lhs.min(&rhs));
+        let min = find_min(&v);
+        assert_eq!(*min.unwrap(), CustomInt::try_new(&v2, -1).unwrap());
+    }
+}
diff --git a/codes/rust_lang/lifetimes/src/io.rs b/codes/rust_lang/lifetimes/src/io.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0f8342e83a34704aa46d882808f59172993f77f6
--- /dev/null
+++ b/codes/rust_lang/lifetimes/src/io.rs
@@ -0,0 +1,19 @@
+use crate::custom_int::CustomInt;
+
+/// 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_custom_int(tab: &Vec<CustomInt>) {
+    for i in tab {
+        println!("{i} ");
+    }
+    println!();
+}
diff --git a/codes/rust_lang/lifetimes/src/lib.rs b/codes/rust_lang/lifetimes/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..239d1374768cf5b5ca2ba754e5ad49e97d720f8d
--- /dev/null
+++ b/codes/rust_lang/lifetimes/src/lib.rs
@@ -0,0 +1,67 @@
+/*!
+lifetimes 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.unwrap() == -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/lifetimes/src/main.rs b/codes/rust_lang/lifetimes/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4ed86dcc78a35eab943f8dedb97c8f33130d604c
--- /dev/null
+++ b/codes/rust_lang/lifetimes/src/main.rs
@@ -0,0 +1,32 @@
+use lifetimes::custom_int::CustomInt;
+use lifetimes::io;
+use lifetimes::something_or_nothing::find_min;
+
+// ANCHOR: main
+fn main() -> Result<(), String> {
+    let v1 = vec![1, 3, 6, 9];
+    let v2 = vec![2, 4, 2, 1];
+    let v3 = vec![7, 4, 5, 3];
+    let v4 = vec![4, 1, 1, 1];
+    let v5 = vec![2, 5, 1, 8];
+    let v6 = vec![5, 1, 5, 2];
+    let v7 = vec![7, 6, 6, 7];
+    let v8 = vec![8, 2, 2, 2];
+    let lhs = vec![
+        CustomInt::try_new(&v1, 1)?,
+        CustomInt::try_new(&v2, -1)?,
+        CustomInt::try_new(&v3, 1)?,
+        CustomInt::try_new(&v4, -1)?,
+        CustomInt::try_new(&v5, 1)?,
+        CustomInt::try_new(&v6, 1)?,
+        CustomInt::try_new(&v7, 1)?,
+        CustomInt::try_new(&v8, 1)?,
+    ];
+
+    println!("Among the custom ints in the list:");
+    io::print_tab_custom_int(&lhs);
+    let min = find_min(&lhs);
+    println!("The minimum is {min}");
+    Ok(())
+}
+// ANCHOR_END: main
diff --git a/codes/rust_lang/lifetimes/src/minimum.rs b/codes/rust_lang/lifetimes/src/minimum.rs
new file mode 100644
index 0000000000000000000000000000000000000000..fdc92933bbb6f8f9bb6acf691ef476441f7badd4
--- /dev/null
+++ b/codes/rust_lang/lifetimes/src/minimum.rs
@@ -0,0 +1,17 @@
+// ANCHOR: minimum
+pub trait Minimum<'a> {
+    fn min(&'a self, rhs: &'a Self) -> &'a Self;
+}
+// ANCHOR_END: minimum
+
+// ANCHOR: min
+impl<'a> Minimum<'a> for i32 {
+    fn min(&'a self, rhs: &'a Self) -> &'a Self {
+        if self < rhs {
+            self
+        } else {
+            rhs
+        }
+    }
+}
+// ANCHOR_END: min
diff --git a/codes/rust_lang/lifetimes/src/something_or_nothing.rs b/codes/rust_lang/lifetimes/src/something_or_nothing.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8ce39362c41bbadf69ed2ffe3a01e9515a508919
--- /dev/null
+++ b/codes/rust_lang/lifetimes/src/something_or_nothing.rs
@@ -0,0 +1,145 @@
+use std::fmt::Display;
+
+use crate::minimum::Minimum;
+
+/// An generic enumerated type that encapsulates and Option<T>.
+// ANCHOR: newtype
+#[derive(Debug)]
+pub struct SomethingOrNothing<T>(Option<T>);
+// ANCHOR_END: newtype
+
+impl<T> SomethingOrNothing<T> {
+    pub fn new(val: T) -> Self {
+        SomethingOrNothing(Some(val))
+    }
+
+    // ANCHOR: newtype_unwrap
+    pub fn unwrap(self) -> T {
+        self.0.unwrap()
+    }
+    // ANCHOR_END: newtype_unwrap
+}
+
+// ANCHOR: newtype_display
+impl<T: Display> std::fmt::Display for SomethingOrNothing<T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match &self {
+            SomethingOrNothing(None) => write!(f, "Nothing.")?,
+            SomethingOrNothing(Some(val)) => write!(f, "Something is: {}", val)?,
+        }
+        Ok(())
+    }
+}
+// ANCHOR_END: newtype_display
+
+// ANCHOR: newtype_default
+impl<T> Default for SomethingOrNothing<T> {
+    /// By Default a [SomethingOrNothing] is a nothing.
+    fn default() -> Self {
+        SomethingOrNothing(None)
+    }
+}
+// ANCHOR_END: newtype_default
+
+// ANCHOR: newtype_partialeq
+impl<T: PartialEq> PartialEq for SomethingOrNothing<T> {
+    fn eq(&self, other: &Self) -> bool {
+        match (&self, &other) {
+            (SomethingOrNothing(None), SomethingOrNothing(None)) => true,
+            (SomethingOrNothing(Some(lhs)), SomethingOrNothing(Some(rhs))) => lhs == rhs,
+            _ => false,
+        }
+    }
+}
+// ANCHOR_END: newtype_partialeq
+
+// ANCHOR: min
+// ANCHOR: impl_min
+impl<'a, T: Minimum<'a> + PartialEq> Minimum<'a> for SomethingOrNothing<T>
+// ANCHOR_END: impl_min
+{
+    fn min(&'a self, rhs: &'a Self) -> &'a Self {
+        match (self, rhs) {
+            (SomethingOrNothing(None), SomethingOrNothing(None)) => self,
+            (SomethingOrNothing(Some(l)), SomethingOrNothing(Some(r))) => {
+                if *l == *l.min(r) {
+                    self
+                } else {
+                    rhs
+                }
+            }
+            (SomethingOrNothing(None), SomethingOrNothing(Some(_))) => rhs,
+            (SomethingOrNothing(Some(_)), SomethingOrNothing(None)) => self,
+        }
+    }
+}
+// ANCHOR_END: min
+
+/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
+/// Returns a [Something] containing the the minimum value
+/// or [Nothing] if no minimum value was found.
+///
+/// # Examples
+///
+/// ```
+/// # use lifetimes::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.unwrap() == 2);
+/// # }
+/// ```
+///
+/// ```
+/// # use lifetimes::something_or_nothing::{SomethingOrNothing, find_min};
+/// # fn main() {
+/// let tab: Vec<i32> = vec![];
+/// let min = find_min(&tab);
+/// assert!(min == SomethingOrNothing::default());
+/// # }
+/// ```
+// ANCHOR: find_min
+pub fn find_min<'a, T: Minimum<'a>>(tab: &'a [T]) -> SomethingOrNothing<&'a T> {
+    // A very elegant fold applied on an iterator
+    tab.iter().fold(SomethingOrNothing::default(), |res, x| {
+        let r = match res {
+            SomethingOrNothing(None) => x,
+            SomethingOrNothing(Some(r)) => r.min(x),
+        };
+        SomethingOrNothing::new(r)
+    })
+}
+// ANCHOR_END: find_min
+
+/// Finds the minimum values contained in two slices and returns the reference
+/// towards the slice that contains it.
+///
+/// # Examples
+///
+/// ```
+/// # use lifetimes::something_or_nothing::{SomethingOrNothing, vec_with_min};
+/// # fn main() {
+/// let tab1 = vec![10, 32, 12, 43, 52, 53, 83, 2, 9];
+/// let tab2 = vec![10, 32, 12, 43, -2, 53, 83, 2, 9];
+///
+/// let min = vec_with_min(&tab1, &tab2).unwrap();
+/// assert!(min == &tab2);
+/// # }
+/// ```
+pub fn vec_with_min<'a, T: Minimum<'a> + PartialEq>(
+    lhs: &'a [T],
+    rhs: &'a [T],
+) -> SomethingOrNothing<&'a [T]> {
+    match (find_min(lhs), find_min(rhs)) {
+        (SomethingOrNothing(None), SomethingOrNothing(None)) => SomethingOrNothing::default(),
+        (SomethingOrNothing(None), SomethingOrNothing(Some(_))) => SomethingOrNothing::new(rhs),
+        (SomethingOrNothing(Some(_)), SomethingOrNothing(None)) => SomethingOrNothing::new(lhs),
+        (SomethingOrNothing(Some(l)), SomethingOrNothing(Some(r))) => {
+            if *l == *l.min(r) {
+                SomethingOrNothing::new(lhs)
+            } else {
+                SomethingOrNothing::new(rhs)
+            }
+        }
+    }
+}
diff --git a/slides/src/SUMMARY.md b/slides/src/SUMMARY.md
index 4c9d844f78e95c27c12bb90dd5991243f695e400..399cd777d11ee1d780ecfcfb6d2c34402f7ef7ca 100644
--- a/slides/src/SUMMARY.md
+++ b/slides/src/SUMMARY.md
@@ -20,6 +20,6 @@
 - [Vecteurs](vec.md).
 - [Les Strings](string.md).
 <!-- - [Itérateurs](iterators.md).
-- [Unsafe Rust](collections.md).
-- [Lifetimes](lifetimes.md). -->
+- [Unsafe Rust](collections.md). -->
+- [Lifetimes](lifetimes.md).
 - [Unsafe](unsafe.md).
diff --git a/slides/src/lifetimes.md b/slides/src/lifetimes.md
new file mode 100644
index 0000000000000000000000000000000000000000..b1d7834c84e47ac4b8c935fa5c8a28ec43752480
--- /dev/null
+++ b/slides/src/lifetimes.md
@@ -0,0 +1,138 @@
+# Lifetimes
+
+## Ressources
+
+* [The Book](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)
+* [The Rustonomicon](https://doc.rust-lang.org/nomicon/lifetimes.html)
+
+## Problématique
+
+```rust [2|3-6|7|] compile_fail
+fn main() {
+    let r;
+    {
+        let x = 5;
+        r = &x;
+    }
+    println!("r: {}", r);
+}
+```
+
+## Durée de vie: annotation
+
+```rust [] compile_fail
+fn main() {
+    let r: &'a i32;        // --------+-- 'a
+    {                      //         |
+        let x: 'b i32 = 5; // -+--'b  |
+        r = &'b x;         //  |      |
+    }                      // -+      |
+    println!("r: {}", r);  // --------+ // x vit plus
+}
+```
+
+* Correction?
+
+## Inférence
+
+* Souvent la durée de vie est **inférée**,
+* Comme pour les **types**, on doit préciser quand il y a un **doute**,
+* Utile que pour la **compilation**: the famous *borrow checker*,
+* Si vous devez annoter votre code, il se peut que vous fassiez un truc trop compliqué.
+
+## Exemple
+
+```rust [8-13|1,7|] compile_fail
+fn longest(x: &str, y: &str) -> &str {
+    if x.len() > y.len() {
+        x
+    } else {
+        y
+    }
+} // return lifetime is... x or y?
+fn main() {
+    let string1 = String::from("abcd");
+    let string2 = "xyz";
+    let result = longest(string1.as_str(), string2);
+    println!("The longest string is {}", result);
+}
+```
+
+## Correction
+
+```rust [1,7|]
+fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
+    if x.len() > y.len() {
+        x
+    } else {
+        y
+    }
+} // all have the same lifetime
+fn main() {
+    let string1 = String::from("abcd");
+    let string2 = "xyz";
+    let result = longest(string1.as_str(), string2);
+    println!("The longest string is {}", result);
+}
+```
+
+## Annotation
+
+* Indique au compilateur les relations de durées de vie,
+* Ne permet pas d'augmenter une durée de vie,
+* Le compilateur vérifie que la durée de vie est **compatible** avec la durée de vie.
+
+```rust [] ignore
+&T        // référence
+&'a T     // référence avec durée de vie a
+&'a mut T // référence mutable avec durée de vie a
+```
+
+## Dans une structure
+
+```rust [1-3|6-8|]
+struct VecView<'a> {
+    view: &'a [i32]
+}
+fn main() {
+    let v = vec![1, 2, 3, 4, 5, 6];
+    let vv = VecView {
+        view: &v[1..4],
+    };
+    println!("view = {:?}", vv.view);
+}
+```
+
+* Le compilateur vérifie que `VecView` ne vit pas plus longtemps que sa référence `view`.
+
+## Élision: fonction
+
+```rust
+fn vecview(v: &[i32], min: usize, max: usize) -> &[i32] {
+    &v[min..max]
+}
+```
+
+* Règle 1: Chaque référence en argument à sa durée de vie,
+* Règle 2: Si unique durée de vie en argument, la sortie obtient la même
+
+## Élision: méthode
+
+```rust [1-3|4-9|]
+struct VecView<'a> {
+    view: &'a [i32]
+}
+impl<'a> VecView<'a> {
+    fn show(&self, original: &[i32]) -> &[i32] {
+        println!("we view {:?}, from {:?}", self.view, original);
+        self.view
+    }
+}
+fn main() {
+    let v = vec![1, 2, 3, 4, 5, 6];
+    let vv = VecView { view: &v[1..4] };
+    vv.show(&v);
+}
+```
+* Règle 3: Si un argument est `&self` ou `&mut self`, la sortie a automatiquement la même durée de vie.
+