#![allow(unused)]
fn main() {
//! This is an example of Rust crate comments (or inner comments).
//! They will be rendered in the front page of your (crate) library.
//!
//! # How to generate the documentation
//!
//! In this program we wrote an algorithm that computes the minimum of
//! a sequence of integers.
//!
//! To create the documentation run the command
//! ```bash
//! cargo doc
//! ```
//! The generated documentation can be found in the `target/doc/collections/index.html` directory
//!
//! To view the documentation type
//! ```bash
//! cargo doc --open
//! ```
//! which will open the browser and show you the documentation.
//!
//! The documentation supports the Common Markdown syntax.
//!
//! Below we will use the `///` comments that will comment the code directly below.
//! We can also use `//` but they will not be rendered.
//! All the lines written here could be enclosed in `/*! ... */` instead of being prefixed by `//!`.
//!
//! For more information about writing documentation [follow that link](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html).
//!
//! # Tooling
//!
//! Also Rust comes with great tooling.
//! - [Clippy](https://doc.rust-lang.org/stable/clippy/): The official Rust linter.
//! - [Rustfmt](https://github.com/rust-lang/rustfmt): The official Rust code formatter.
pub mod io;
pub mod minimum;
pub mod something_or_nothing;
#[test]
fn test_creation() {
use something_or_nothing::SomethingOrNothing;
let n1: SomethingOrNothing<i32> = SomethingOrNothing::default();
assert!(n1 == SomethingOrNothing::Nothing);
let n2: SomethingOrNothing<i32> = SomethingOrNothing::Something(1);
assert!(n2 == SomethingOrNothing::Something(1));
}
#[cfg(test)]
mod tests {
use crate::minimum::Minimum;
use crate::something_or_nothing::{SomethingOrNothing, find_min};
#[test]
#[should_panic]
fn test_failure_creation() {
let n2: SomethingOrNothing<i32> = SomethingOrNothing::Something(1);
assert!(n2 == SomethingOrNothing::Nothing);
assert!(n2 == SomethingOrNothing::Something(2));
}
#[test]
fn test_min() {
let a = [1, 5, -1, 2, 0, 10, 11, 0, 3];
let min = find_min(&a);
assert!(min == SomethingOrNothing::Something(-1));
}
#[test]
fn test_min_something_or_nothing() {
let x = SomethingOrNothing::Something(5i32);
let y = SomethingOrNothing::Something(10i32);
let z = SomethingOrNothing::Nothing;
assert!(x.min(y) == x);
assert!(y.min(x) == x);
assert!(z.min(y) == y);
assert!(y.min(z) == y);
assert!(z.min(z) == z);
}
}
}
use collections::io;
use collections::something_or_nothing::find_min;
fn main() -> Result<(), String> {
//ANCHOR: vec
let tab: Vec<i32> = io::read_command_line(10usize);
println!("Among the Somethings in the list:");
io::print_tab(&tab);
let min = find_min(&tab);
min.print();
//ANCHOR_END: vec
let tab = io::read_command_line_str()?;
println!("Among the Somethings in the list:");
io::print_tab(&tab);
let min = find_min(&tab);
min.print();
//ANCHOR: ref
println!("Among the Somethings in the list:");
io::print_tab(&tab[1..9]);
let min = find_min(&tab[1..9]);
min.print();
//ANCHOR_END: ref
//ANCHOR: tab
let tab = [1, 2, 3, 4, 5, 6];
println!("Among the Somethings in the list:");
io::print_tab(&tab);
let min = find_min(&tab);
min.print();
//ANCHOR_END: tab
Ok(())
}
#![allow(unused)]
fn main() {
//! Contains functions to interact with the user, either
//! by reading inputs from the terminal, either by writing values
//! in it.
use rand::Rng;
// ANCHOR: read_command_line
/// Poorly emulates the parsing of a command line.
pub fn read_command_line(len: usize) -> Vec<i32> {
let mut rng = rand::rng();
// ANCHOR: vec_new
let mut v: Vec<i32> = Vec::new();
// ANCHOR_END: vec_new
// ANCHOR: vec_for
for _i in 0..len {
// ANCHOR: vec_push
v.push(rng.random());
// ANCHOR_END: vec_push
}
// ANCHOR_END: vec_for
v
}
// ANCHOR_END: read_command_line
// ANCHOR: read_command_line_str
/// Poorly emulates the parsing of a command line.
pub fn read_command_line_str() -> Result<Vec<i32>, String> {
// ANCHOR: from
let mut s = String::from("20 10 48 58 29 0 58 -10 39 5485 394");
// ANCHOR_END: from
// ANCHOR: push_str
s.push_str(" -100");
// ANCHOR_END: push_str
// ANCHOR: push_char
s.push(' ');
s.push('1');
s.push('2');
// ANCHOR_END: push_char
// ANCHOR: split
let s: Vec<&str> = s.split_ascii_whitespace().collect();
// ANCHOR_END: split
// ANCHOR: string_for
let mut v = Vec::new();
for i in 0..s.len() {
v.push(
// ANCHOR: conversion
s.get(i)
.ok_or(String::from("Unable to index"))?
.parse()
.map_err(|_| format!("Unable to parse {}", s[i]))?,
// ANCHOR_END: conversion
);
}
// ANCHOR_END: string_for
Ok(v)
}
// ANCHOR_END: read_command_line_str
/// Prints all the elements of the `tab`.
/// Tab is borrowed here
// ANCHOR: print_tab
pub fn print_tab(tab: &[i32]) {
for t in tab {
print!("{} ", t);
}
println!();
}
// ANCHOR_END: print_tab
}
#![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 collections::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 }
}
}
#[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);
}
}
}
//! Contains the core logic of the library, allowing to store generic values
//! (or their absence) and manipulate them.
use crate::minimum::Minimum;
/// A generic enumerated type that has two variants.
///
/// - Nothing
/// - Something
#[derive(Clone, Copy)]
pub enum SomethingOrNothing<T> {
/// A [SomethingOrNothing::Nothing]
Nothing,
/// A [SomethingOrNothing::Something] encapsulating a T
Something(T),
}
impl<T: std::fmt::Display> SomethingOrNothing<T> {
/// A method that prints the content of a SomethingOrNothing.
pub fn print(&self) {
match self {
SomethingOrNothing::Nothing => println!("Nothing."),
SomethingOrNothing::Something(val) => println!("Something is: {}", val),
}
}
}
/// Implementation of the [Default] trait that creates a [SomethingOrNothing]
/// that is a `Nothing` variant.
///
/// # Example
///
/// ```
/// # use collections::something_or_nothing::SomethingOrNothing;
/// # fn main() {
/// let def: SomethingOrNothing<i32> = SomethingOrNothing::default();
/// assert!(def == SomethingOrNothing::Nothing);
/// # }
/// ```
impl<T> Default for SomethingOrNothing<T> {
/// By Default a [SomethingOrNothing] is a nothing.
fn default() -> Self {
SomethingOrNothing::Nothing
}
}
/// Implementation of the [PartialEq] trait that is useful for tests.
impl<T: PartialEq> PartialEq for SomethingOrNothing<T> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(SomethingOrNothing::Nothing, SomethingOrNothing::Nothing) => true,
(SomethingOrNothing::Something(lhs), SomethingOrNothing::Something(rhs)) => {
*lhs == *rhs
}
_ => false,
}
}
}
/// Implementation of the [Minimum] trait used for comparing values
/// in this crate.
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.
///
/// # Example
///
/// ```
/// # use collections::something_or_nothing::{SomethingOrNothing, find_min};
/// # fn main() {
/// let tab = vec![10, 32, 12, 43, 52, 53, 83, 2, 9];
/// let min = find_min(&tab);
/// assert!(min == SomethingOrNothing::Something(2));
/// # }
/// ```
// ANCHOR: find_min
pub fn find_min<T: Minimum>(tab: &[T]) -> 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
}
// ANCHOR_END: find_min