Rust : packages
lib.rs
//J'ai créé une librairie avec cargo new malib --lib
//Je suis ici dans la crate (la crate, c'est ce fichier !)
//Je pourrais avoir deux crate dans le même package (un main.rs et un lib.rs)
//
//ici j'ai plusieurs modules, certains sont imbriqués. Ils sont privés par défaut
//Un parent ne peut pas utiliser ses enfants privés, mais l'inverse est vrai.
//
//Les règles sont les suivantes:
//* Une fonction/module peut toujours appeller ses soeurs
//* Pour appeller les enfants de ses soeurs, ceux-ci doivent être publics
//* On peut appeller un module ou une fonction marquée publique, si on a accès à son parent
//
//Le module suivant est dans un fichier à part;
//J'appelle son mod uniquement ici, je n'ai pas besoin de le remettre dans le deuxième fichier
//qui s'appelle front_of_house.rs
mod front_of_house;
pub use crate::front_of_house::hosting;
//Je vais créer ma fonction publique, qui elle sera accessible de l'extérieur
//eat_at_restaurant et front_of_house sont siblings, je peux donc appeller l'un
//depuis l'autre
pub fn get_seated() {
//Je peux appeller une fonction dans la même crate par un chemin absolu...
//crate est un mot-clef
crate::front_of_house::hosting::add_to_waitlist();
//...ou relatif
front_of_house::hosting::add_to_waitlist();
}
fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
//Ici, le mot-clef super permet d'appeller quelque chose dans le parent
//Un peu comme utiliser .. dans un système de fichiers
super::deliver_order();
}
fn cook_order() {}
//On peut aussi rendre un struct ou un enum public
//Pour un struct, ses éléments restent privés par défaut
pub struct Breakfast {
pub toast: String,
//seasonal_fruit est privé
seasonal_fruit: String,
}
impl Breakfast {
//Ici, j'ai une méthode publique pour construire mon objet
//et le renvoyer
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
//Les éléments d'un enum public sont publics
//par défaut
pub enum Appetizer {
Soup,
Salad,
}
}
pub fn eat_at_restaurant() {
// Order a breakfast in the summer with Rye toast
let mut meal = back_of_house::Breakfast::summer("Rye");
// Change our mind about what bread we'd like
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
// The next line won't compile if we uncomment it; we're not allowed
// to see or modify the seasonal fruit that comes with the meal
// meal.seasonal_fruit = String::from("blueberries");
//
//Calling my public enum:
//back_of_house is a sibling so I can access it
//the enum itself is public so no issues
let order1 = back_of_house::Appetizer::Soup;
}
//On peut utiliser le mot use pour raccourcir les appels
//Un peu comme un lien symbolique
//...mais cela ne marche que dans le scope où l'on utilise use
//La façon habituelle d'appeller des modules et des fonctions est d'appeller
//son parent...
use crate::front_of_house::hosting;
//Ceci ne fonctionne pas !
//mod customer_notworking {
// pub fn somethingsomething() {
// hosting::add_to_waitlist();
// }
//}
//Ceci fonctionne
mod customer {
pub fn something() {
use crate::front_of_house::hosting;
hosting::add_to_waitlist;
}
}
//...en revanche la façon idiomatique d'appeller des enums
//et des structs est de les appeller directement
//(Sauf si on en appelle 2 qui ont le même nom)
use std::collections::HashMap;
fn notmain() {
let mut map = HashMap::new();
map.insert(1, 2);
}
//On peut aussi faire des alias comme en Python...
use std::io::Result as IoResult;
//On peut combiner pub et use pour importer du code
//et le rendre public
//Cela s'appelle du re-exporting
pub use crate::front_of_house::hosting;
pub fn whatever() {
hosting::add_to_waitlist();
}
//Si l'on a beaucoup d'imports, on peut factoriser
//Ceci
use std::cmp::Ordering;
use std::io;
//Peut s'écrire
use std::{cmp::Ordering, io};
//On peut importer tous les éléments publics dans le scope
use std::collections::*;
front_of_house.rs
//Je rend le module public pour pouvoir l'appeller dans eat_at_restaurant()
pub mod hosting {
pub fn add_to_waitlist() {
//Ici, je peux appeller une fonction privée,
//par exemple seat_at_table()
}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}