#![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_minimum;
pub mod io;
pub mod minimum;
#[cfg(test)]
mod tests {
use crate::find_minimum::{
find_min_amongst_arrays_by_hand, find_min_amongst_arrays_qm_op, find_min_with_option,
find_min_with_panic, find_min_with_result,
};
const TAB: [i32; 9] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
const TAB_B: [i32; 9] = [22, 34, 11, 4, 52, 99, 71, 13, 43];
const TAB_EMPTY: [i32; 0] = [];
const MIN_TAB: i32 = 2;
#[test]
fn test_find_min_option() {
let min = find_min_with_option(&TAB);
assert!(min == Some(MIN_TAB));
}
#[test]
fn test_find_min_option_empty() {
let min = find_min_with_option(&TAB_EMPTY);
assert!(min.is_none());
}
#[test]
fn test_find_min_result() {
let min = find_min_with_result(&TAB);
assert!(min == Ok(MIN_TAB));
}
#[test]
fn test_find_min_result_empty() {
let min = find_min_with_result(&TAB_EMPTY);
assert!(min.is_err());
}
#[test]
fn test_find_min_panic() {
let min = find_min_with_panic(&TAB);
assert!(min == MIN_TAB);
}
#[test]
#[should_panic]
fn test_find_min_panic_empty() {
let _min = find_min_with_panic(&TAB_EMPTY);
}
#[test]
fn test_find_min_amongst_arrays_bh() {
let min = find_min_amongst_arrays_by_hand(&TAB, &TAB_B);
assert!(min == Ok(MIN_TAB));
}
#[test]
fn test_find_min_amongst_arrays_qm() {
let min = find_min_amongst_arrays_qm_op(&TAB, &TAB_B);
assert!(min == Ok(MIN_TAB));
}
#[test]
fn test_find_min_amongst_arrays_bh_empty() {
let min = find_min_amongst_arrays_by_hand(&TAB, &TAB_EMPTY);
assert!(min.is_err());
}
#[test]
fn test_find_min_amongst_arrays_qm_empty() {
let min = find_min_amongst_arrays_qm_op(&TAB, &TAB_EMPTY);
assert!(min.is_err());
}
}
}
use gestion_erreurs::find_minimum::{
FindMinError::EmptyList, FindMinError::UnsupportedError, find_min_amongst_arrays_qm_op,
find_min_with_option, find_min_with_result,
};
use gestion_erreurs::io;
fn main() {
let tab = io::read_command_line_correct();
println!("Among the elements in the list:");
io::print_tab(&tab);
let min = find_min_with_option(&tab);
match min {
Some(val) => print!("The minimum value is {}", val),
None => eprintln!("There is no minimum since the list is empty"),
}
println!("");
println!("");
let tab_empty = io::read_empty_command_line();
println!("Among the elements in the list:");
io::print_tab(&tab_empty);
//ANCHOR: parse_result
let min = find_min_with_result(&tab_empty);
match min {
Ok(val) => print!("The minimum value is {}", val),
Err(EmptyList) => eprintln!("The array is empty"),
Err(UnsupportedError(msg)) => panic!("Unsupported error : {}", msg),
}
//ANCHOR_END: parse_result
println!("Among the elements in the lists:");
io::print_tab(&tab);
io::print_tab(&tab_empty);
let min = find_min_amongst_arrays_qm_op(&tab, &tab_empty);
match min {
Ok(val) => print!("The minimum value is {}", val),
Err(EmptyList) => eprintln!("One or both arrays are empty"),
Err(UnsupportedError(msg)) => panic!("Unsupported error : {}", msg),
}
}
//! Contains the core logic of the library, allowing to store generic values
//! (or their absence) and manipulate them.
//! We demonstrates three kind of way to deal with errors
use crate::minimum::Minimum;
// ANCHOR: find_min_error
#[derive(PartialEq)]
pub enum FindMinError {
EmptyList,
UnsupportedError(String),
}
// ANCHOR_END: find_min_error
use crate::find_minimum::FindMinError::EmptyList;
/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
/// Returns a [Option::Some] containing the minimum value
/// or [Option::None] if no minimum value was found.
///
/// # Example
///
/// ```
/// # use gestion_erreurs::find_minimum::{find_min_with_option};
/// # fn main() {
/// let tab = [10, 32, 12, 43, 52, 53, 83, 2, 9];
/// let min = find_min_with_option(&tab);
/// assert!(min == Some(2));
/// # }
/// ```
// ANCHOR: min_with_option
pub fn find_min_with_option<T: Minimum>(tab: &[T]) -> Option<T> {
let mut minimum = None;
// Here, if T is Copyable, t is not moved in the loop
for t in tab {
minimum = Minimum::min(minimum, Some(*t));
}
minimum
}
// ANCHOR_END: min_with_option
/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
/// Returns a [Result::Ok] containing the minimum value
/// or an [Result::Err] containing the error, if no minimum value was found.
///
/// # Example
///
/// ```
/// # use gestion_erreurs::find_minimum::{find_min_with_result};
/// # fn main() {
/// let tab = [10, 32, 12, 43, 52, 53, 83, 2, 9];
/// let min = find_min_with_result(&tab);
/// assert!(min == Ok(2));
/// # }
/// ```
///
/// ```
/// # use gestion_erreurs::find_minimum::{find_min_with_result};
/// # fn main() {
/// let tab : [i32; 0] = [];
/// let min = find_min_with_result(&tab);
/// assert!(min.is_err());
/// # }
/// ```
// ANCHOR: min_with_result
pub fn find_min_with_result<T: Minimum>(tab: &[T]) -> Result<T, FindMinError> {
let mut minimum = None;
// Here, if T is Copyable, t is not moved in the loop
for t in tab {
minimum = Minimum::min(minimum, Some(*t));
}
match minimum {
Some(val) => Ok(val),
None => Err(EmptyList),
}
}
// ANCHOR_END: min_with_result
/// Computes the minimum of an Array of a type T which implements the [Minimum] trait.
/// Returns a T which is the minimum value
/// or panics if no minimum value was found.
///
/// # Example
///
/// ```
/// # use gestion_erreurs::find_minimum::{find_min_with_panic};
/// # fn main() {
/// let tab = [10, 32, 12, 43, 52, 53, 83, 2, 9];
/// let min = find_min_with_panic(&tab);
/// assert!(min == 2);
/// # }
/// ```
///
/// ```should_panic
/// # use gestion_erreurs::find_minimum::{find_min_with_panic};
/// # fn main() {
/// let tab : [i32; 0] = [];
/// let _min = find_min_with_panic(&tab);
/// # }
/// ```
// ANCHOR: min_with_panic
pub fn find_min_with_panic<T: Minimum>(tab: &[T]) -> T {
let mut minimum = None;
// Here, if T is Copyable, t is not moved in the loop
for t in tab {
minimum = Minimum::min(minimum, Some(*t));
}
// We decide that we cannot compute the minimum of an empty array
match minimum {
Some(val) => val,
None => panic!("The array is empty"),
}
}
// ANCHOR_END: min_with_panic
/// Computes the minimum amongst two Arrays of a type T which implements the [Minimum] trait.
/// Returns a [Result::Ok] containing the minimum value
/// or an [Result::Err] containing the error, if no minimum value was found.
///
/// We deal with errors in underlying function calls without the [?] operator.
///
/// # Example
///
/// ```
/// # use gestion_erreurs::find_minimum::{find_min_amongst_arrays_by_hand};
/// # fn main() {
/// let tab_a = [10, 32, 12, 43, 52, 53, 83, 2, 9];
/// let tab_b = [22, 34, 11, 4, 52, 99, 71, 13, 43];
/// let min = find_min_amongst_arrays_by_hand(&tab_a, &tab_b);
/// assert!(min == Ok(2));
/// # }
/// ```
///
/// ```
/// # use gestion_erreurs::find_minimum::{find_min_amongst_arrays_by_hand};
/// # fn main() {
/// let tab_a = [10, 32, 12, 43, 52, 53, 83, 2, 9];
/// let tab_b : [i32; 0] = [];
/// let min = find_min_amongst_arrays_by_hand(&tab_a, &tab_b);
/// assert!(min.is_err());
/// # }
/// ```
// ANCHOR: min_two_tabs_hand
pub fn find_min_amongst_arrays_by_hand<T: Minimum>(
lhs: &[T],
rhs: &[T],
) -> Result<T, FindMinError> {
let min_result = find_min_with_result(lhs);
let min_l = if let Ok(x) = min_result {
x
} else {
// Since tmp is not Ok, we return the error to the caller
return min_result;
};
let min_result = find_min_with_result(rhs);
let min_r = if let Ok(x) = min_result {
x
} else {
// Since tmp is not Ok, we return the error to the caller
return min_result;
};
Ok(min_l.min(min_r))
}
// ANCHOR_END: min_two_tabs_hand
/// Computes the minimum amongst two Arrays of a type T which implements the [Minimum] trait.
/// Returns a [Result::Ok] containing the minimum value
/// or an [Result::Err] containing the error, if no minimum value was found.
///
/// We deal with errors in underlying function with the [?] operator.
///
/// # Example
///
/// ```
/// # use gestion_erreurs::find_minimum::{find_min_amongst_arrays_qm_op};
/// # fn main() {
/// let tab_a = [10, 32, 12, 43, 52, 53, 83, 2, 9];
/// let tab_b = [22, 34, 11, 4, 52, 99, 71, 13, 43];
/// let min = find_min_amongst_arrays_qm_op(&tab_a, &tab_b);
/// assert!(min == Ok(2));
/// # }
/// ```
///
/// ```
/// # use gestion_erreurs::find_minimum::{find_min_amongst_arrays_qm_op};
/// # fn main() {
/// let tab_a = [10, 32, 12, 43, 52, 53, 83, 2, 9];
/// let tab_b : [i32; 0] = [];
/// let min = find_min_amongst_arrays_qm_op(&tab_a, &tab_b);
/// assert!(min.is_err());
/// # }
/// ```
// ANCHOR: min_two_tabs_qm
pub fn find_min_amongst_arrays_qm_op<T: Minimum>(lhs: &[T], rhs: &[T]) -> Result<T, FindMinError> {
// The question mark operator will unpack the value if the function returns [Result::Ok]
// or end the function and return the [Result:Err] to the caller.
let min_l = find_min_with_result(lhs)?;
let min_r = find_min_with_result(rhs)?;
Ok(min_l.min(min_r))
}
// ANCHOR_END: min_two_tabs_qm
#![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() -> [i32; 9] {
[10, 32, 12, 43, 52, 53, 83, 2, 9]
}
/// Poorly emulates the parsing of a command line.
pub fn read_empty_command_line() -> [i32; 0] {
[]
}
/// Prints all the elements of the `tab`.
/// Tab is borrowed here
pub fn print_tab(tab: &[i32]) {
print!("[ ");
for t in tab {
print!("{} ", t);
}
println!("]");
}
}
#![allow(unused)]
fn main() {
//! 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 gestion_erreurs::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 }
}
}
// ANCHOR: min_for_option
impl<T: Minimum> Minimum for Option<T> {
fn min(self, rhs: Self) -> Self {
match self {
Some(val_l) => Some(match rhs {
Some(val_r) => val_l.min(val_r),
None => val_l,
}),
None => match rhs {
Some(val_r) => Some(val_r),
None => None,
},
}
}
}
// ANCHOR_END: min_for_option
#[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);
}
}
}