iterateurs

src/lib.rs

#![allow(unused)]
fn main() {
//! 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;
pub mod io;

#[cfg(test)]
mod tests {
    use crate::find::{find_absolute_minimum, find_minimum};
    const VEC: [i32; 9] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
    const VEC_2: [i32; 9] = [-10, 32, 12, -43, 52, -53, 83, -2, 9];
    const MIN_VEC: i32 = 2;
    const ABS_MIN_VEC_2: i32 = -2;

    #[test]
    fn test_find_minimum() {
        let min: Option<i32> = find_minimum(&(VEC.to_vec()));

        assert!(min == Some(MIN_VEC));
    }

    #[test]
    fn test_find_absolute_minimum() {
        let min: Option<i32> = find_absolute_minimum(&(VEC_2.to_vec()));

        assert!(min == Some(ABS_MIN_VEC_2));
    }
}
}

src/main.rs

use iterateurs::find::{find_absolute_minimum, find_even_minimum, find_minimum};
use iterateurs::io;

fn main() {
    let v = io::read_command_line_correct();
    println!("Among the elements in the list:");
    io::print_vec(&v);

    let min = find_minimum(&v);
    match min {
        Some(val) => println!("The minimum value is {}", val),
        None => eprintln!("There is no minimum"),
    }

    let min = find_absolute_minimum(&v);
    match min {
        Some(val) => println!("The minimum by absolute value is {}", val),
        None => eprintln!("There is no minimum"),
    }

    let min = find_even_minimum(&v);
    match min {
        Some(val) => println!("The smallest even value is {}", val),
        None => eprintln!("There is no minimum"),
    }
}

src/find.rs

//! Contains the core logic of the library, allowing to store generic values
//! (or their absence) and manipulate them.
//! We demonstrate several ways to process collections with iterators.

/// Computes the minimum of a vector of i32.
/// Returns a [Option::Some] containing the minimum value
/// or [Option::None] if the vec was empty.
///
/// # Example
///
/// ```
/// # use iterateurs::find::{find_minimum};
/// # fn main() {
/// let v = vec![-2, 5, 18, 65, 22, 56, -30];
/// let min = find_minimum(&v);
/// assert!(min == Some(-30));
/// # }
/// ```
// ANCHOR: find_minimum
pub fn find_minimum(v: &Vec<i32>) -> Option<i32> {
    v.iter().fold(None, |acc, current| {
        let next_acc = if let Some(val) = acc {
            if val <= *current { val } else { *current }
        } else {
            *current
        };
        Some(next_acc)
    })
}
// ANCHOR_END: find_minimum

/// Computes the smallest even number in a vector of i32.
/// Returns a [Option::Some] containing the smallest even number
/// or [Option::None] if the vec was empty.
///
/// # Example
///
/// ```
/// # use iterateurs::find::{find_even_minimum};
/// # fn main() {
/// let v = vec![15, 64, 47, 2, 1, 53, 22];
/// let min = find_even_minimum(&v);
/// assert!(min == Some(2));
/// # }
/// ```
// ANCHOR: find_even_minimum
pub fn find_even_minimum(v: &Vec<i32>) -> Option<i32> {
    v.iter().filter(|i| *i % 2 == 0).fold(None, |acc, current| {
        let next_acc = if let Some(val) = acc {
            if val <= *current { val } else { *current }
        } else {
            *current
        };
        Some(next_acc)
    })
}
// ANCHOR_END: find_even_minimum

/// Computes the minimum absolute value of a vector of i32.
/// Returns a [Option::Some] containing the minimum abs value
/// or [Option::None] if the vec was empty.
///
/// # Example
///
/// ```
/// # use iterateurs::find::{find_absolute_minimum};
/// # fn main() {
/// let v = vec![-2, 5, 18, 65, 22, 56, -30];
/// let min = find_absolute_minimum(&v);
/// assert!(min == Some(-2));
/// # }
/// ```
// ANCHOR: find_absolute_minimum
pub fn find_absolute_minimum(v: &Vec<i32>) -> Option<i32> {
    // ANCHOR: find_absolute_minimum_1
    let signs = v.iter().map(|i| i.signum());
    let abs_values = v.iter().map(|i| i.abs());
    // ANCHOR_END: find_absolute_minimum_1
    // ANCHOR: find_absolute_minimum_2
    signs
        .zip(abs_values)
        // ANCHOR_END: find_absolute_minimum_2
        // ANCHOR: find_absolute_minimum_3
        .fold(None, |acc, (c_sign, c_abs_v)| {
            let next_acc = if let Some((sign, abs_v)) = acc {
                if abs_v <= c_abs_v {
                    (sign, abs_v)
                } else {
                    (c_sign, c_abs_v)
                }
            } else {
                (c_sign, c_abs_v)
            };
            Some(next_acc)
        })
        // ANCHOR_END: find_absolute_minimum_3
        // ANCHOR: find_absolute_minimum_4
        .map(|(sign, abs_v)| sign * abs_v)
    // ANCHOR_END: find_absolute_minimum_4
}
// ANCHOR_END: find_absolute_minimum

src/io.rs

#![allow(unused)]
fn main() {
//! Contains functions to interact with the user, either
//! by reading inputs from the terminal, either by writing values
//! in it.

/// Poorly emulates the parsing of a command line.
pub fn read_command_line_correct() -> Vec<i32> {
    vec![-10, 32, 12, -43, 52, -53, 83, -2, 9]
}

/// Poorly emulates the parsing of a command line.
pub fn read_empty_command_line() -> Vec<i32> {
    vec![]
}

/// Prints all the elements of the vector.
/// vector is borrowed here
pub fn print_vec(v: &Vec<i32>) {
    print!("[ ");
    for t in v {
        print!("{} ", t);
    }
    println!("]");
}
}