Cartouche

Champ Valeur
Auteur·e Élise
Édition 2024-07-24
Durée 2 séances (un jour)
Taille des équipes 1 personne
Rendu via git, dépôt $YEAR_rust_c2, droits en lecture à delivery_collector

Règlement

Prenez connaissance du règlement ici

L’intégralité de la bibliothèque standard est autorisée. Vous êtes encouragés à vous servir des outils qu’elle vous propose s’ils résolvent un de vos problèmes. Votre objectif c’est d’éviter de ré-inventer la roue quand ça n’est pas nécessaire.

Introduction

Notre premier objectif, ça va être de configurer votre environnement de travail de sorte à pouvoir travailler avec le Rust.

Notions :

  • modification de chaînes de caractères
  • recherche dans une chaîne de caractères
  • itérateurs

Notation

Critère Points Accessibles
E1 translate char 3
E2 translate 4
E3 chaîne la plus grande 4
E4 trier les chaînes par traille 3
E5 extraire une valeur INI 3
E6 types INI 3
Total des critères 20
Malus par lignes en faute -0,5
Malus dépôt sale -5
Total N/A

Exercice 1 : translate char

Fichier à rendre : src/lib.rs (vous pouvez supprimer src/main.rs)

Écrivez une fonction translate_char qui prend en paramètre :

  • une référence mutable sur une chaîne ;
  • un caractère à remplacer ;
  • le caractère par lequel replacer.

Votre fonction doit modifier la chaîne reçue de sorte que toutes les instances du premier caractère soit modifiées par le second.

La fonction ne doit pas avoir de problème à fonctionner sur des caractères UTF-8 de tailles différentes.

let mut s1 = String::from("abricot");
translate_char(&mut s1, 'a', 'あ');
translate_char(&mut s1, 'i', 'い');
assert_eq!(s1, "あbrいcot");

Exercice 2 : translate

Fichier à rendre : src/lib.rs (ajouts)

Écrivez la fonction translate qui prend en paramètre :

  • une référence mutable sur une chaîne ;
  • une string slice qui contient les caractères à remplacer ;
  • une string slice qui contient les caractères par lesquels les remplacer.
let mut s1 = String::from("abricot");
translate(&mut s1, "ai", "あい");
assert_eq!(s1, "あbrいcot");

Exercice 3 : chaîne la plus grande

Fichier à rendre : src/lib.rs (ajouts)

Écrivez la fonction longest_str. Elle doit prendre deux string slices en paramètre, et renvoyer celle qui contient le plus de caractères.

La durée de vie de vos référence va probablement vous embêter à la compilation.

Exercice 4 : trier les chaînes par taille

Fichier à rendre : src/lib.rs (ajouts)

Écrivez la fonction sort_string. Elle doit prendre en paramètre une slice de tableau de chaînes de caractères. Elle doit aussi prendre une énumération Order qui comporte deux variantes, une pour trier du plus petit au plus grand, une autre pour trier du plus grand au plus petit.

Si deux chaînes ont le même nombre de caractères, triez-les par nombre d’octets.

Renvoyez une slice triée.

Exercice 5 : extraire une valeur INI

Fichier à rendre : src/lib.rs (ajouts)

Écrivez la fonction ini_get_value, qui prend en paramètre une string slice qui représente la configuration INI et une string slice qui est le nom de la valeur qui nous intéresse.

  • Si elle trouve la clé, elle renvoie la valeur associée.
  • Sinon elle renvoie une erreur comme quoi elle n’a rien trouvé.
  • Si une ligne ne contient pas de symbole = renvoyez une erreur comme quoi le texte n’est pas au format INI.

Cela signifie que vous devez avoir votre propre énumération pour vos erreurs (avec deux variantes) et que vous devez renvoyer un Result<T, E>T est le type de renvoi normal et E le type de votre énumération d’erreur.

Exemple de test unitaire :

let ini_contents = r#"
first_name=sarah
last_name=connor
yob=1965
occupation=anti skynet activist
"#;
let last_name = ini_get_value(&ini_contents, "last_name").expect("last_name to be present");
assert_eq!(last_name, "connor");

match ini_get_value(&ini_contents, "potato") {
	Ok(_) => panic!("field potato to not yield any result"),
	// pour la variante Err, vérifiez que l'erreur indique bien que
	// l'élément n'est pas trouvé, mais pas que l'INI est invalide
	// (car il est valide)
}

Exercice 6 : types INI

Fichier à rendre : src/lib.rs (ajouts)

Écrivez une enum IniValue avec une variante Text qui contient une String et une variante Number qui contient un i32.

Écrivez la fonction ini_get_value2. Elle à le même comportement, sauf que lorsque la clé est trouvée, elle doit essayer de parser le nombre. Si le nombre est parsé correctement, il est renvoyé dans un IniValue::Number. Sinon la valeur est renvoyée en chaîne de caractère dans un IniValue::Text.

let ini_contents = r#"
first_name=sarah
last_name=connor
yob=1965
occupation=anti skynet activist
"#;
if let Ok(IniValue::String(last_name)) = ini_get_value(&ini_contents, "last_name") {
    assert_eq!(last_name, "connor");
} else {
    panic!();
}
if let Ok(IniValue::Number(yob)) = ini_get_value(&ini_contents, "yob") {
    assert_eq!(yob, 1965);
} else {
    panic!();
}