modules_visibilite

src/lib.rs

#![allow(unused)]
fn main() {
// ANCHOR: lib_modules
/*!
modules_visibilite illustrates the concepts of **modules** and **visibility**.
*/

// The size of the tab
const SIZE: usize = 9;

pub mod io;
mod minimum;
pub mod something_or_nothing;
// ANCHOR_END: lib_modules
}

src/main.rs

// ANCHOR: main_imports
use modules_visibilite::io;
use modules_visibilite::something_or_nothing::find_min;
// ANCHOR_END: main_imports

fn main() {
    // modules_visibilite::io is imported but not read_command_line
    let tab = io::read_command_line();
    println!("Among the Somethings in the list:");
    // modules_visibilite::io is imported but not print_tab
    io::print_tab(&tab);
    // modules_visibilite::something_or_nothing::find_min is imported and can be used directly
    let min = find_min(&tab);
    min.print();
}

src/io.rs

#![allow(unused)]
fn main() {
// Poorly emulates the parsing of a command line.
pub fn read_command_line() -> [i32; crate::SIZE] {
    [10, 32, 12, 43, 52, 53, 83, 2, 9]
}

// Prints all the elements of the `tab`.
// Tab is borrowed here
// ANCHOR: pub_fn
pub fn print_tab(tab: &[i32; crate::SIZE]) {
    for t in tab {
        print!("{} ", t);
    }
    println!();
}
// ANCHOR_END: pub_fn
}

src/minimum.rs

#![allow(unused)]
fn main() {
// ANCHOR: trait
pub trait Minimum: Copy {
    fn min(self, rhs: Self) -> Self;
}
// ANCHOR_END: trait

impl Minimum for i32 {
    fn min(self, rhs: Self) -> Self {
        if self < rhs { self } else { rhs }
    }
}
}

src/something_or_nothing.rs

#![allow(unused)]
fn main() {
// ANCHOR: minimum
use crate::minimum::Minimum;
// ANCHOR_END: minimum

// ANCHOR: pub_enum
#[derive(Clone, Copy)]
pub enum SomethingOrNothing<T> {
    Nothing,
    Something(T),
}
// ANCHOR_END: pub_enum

// ANCHOR: pub_method
impl<T: std::fmt::Display> SomethingOrNothing<T> {
    pub fn print(&self) {
        match self {
            SomethingOrNothing::Nothing => println!("Nothing."),
            SomethingOrNothing::Something(val) => println!("Something is: {}", val),
        }
    }
}
// ANCHOR_END: pub_method

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 minimum value
// or [SomethingOrNothing::Nothing] if no minimum value was found.
pub fn find_min<T: Minimum>(tab: &[T; crate::SIZE]) -> SomethingOrNothing<T> {
    let mut minimum = SomethingOrNothing::Nothing;
    // Here, if T is Copyable, t is not moved in the loop
    for t in tab {
        minimum = minimum.min(SomethingOrNothing::Something(*t));
    }
    minimum
}
}