Documentation
use csv::Writer;

use std::error::Error;
use std::fmt::Debug;
use std::io;
use serde::{Serialize, Deserialize};


#[derive(Serialize, Deserialize, Debug)]
pub struct T {}


//STAMPA                            fn print(&self)
pub trait Print {
    fn print(&self)
    where
        Self: Debug,
    {
        println!("{:?}", self);
    }
}
impl Print for u32 {}
impl Print for String {}
impl Print for &str {}
impl Print for i128 {}
impl Print for f64 {}

//È NUMERO?                         fn is_number(&self) -> bool;
pub trait IsNumber {               
    fn is_number(&self) -> bool;
}
impl IsNumber for String {
    fn is_number(&self) -> bool {
        let mut vec = Vec::new();
        let c = self.len();
        for i in self.chars() {
            if i.is_numeric() {
                vec.push(i);
                if vec.len() == c {
                    return true;
                }
            }
        }
        false
    }
}

//È LETTERA?                        fn is_alphabetic(&self) -> bool;
pub trait IsAlphabetic {
    fn is_alphabetic(&self) -> bool;
}
impl IsAlphabetic for String {
    fn is_alphabetic(&self) -> bool {
        let mut vec = Vec::new();
        let c = self.len();
        for i in self.chars() {
            if i.is_alphabetic() {
                vec.push(i);
                if vec.len() == c {
                    return true;
                }
            }
        }
        false
    }
}

//CONVERTI STRINGA IN NUMERO        fn to_u32(&self) -> u32;    
pub trait ToNumber {
    fn to_u32(&self) -> u32;
    fn to_u64(&self) -> u64;
    fn to_i128(&self) -> i128;
    fn to_f64(&self) -> f64;
}
impl ToNumber for String {
    fn to_u32(&self) -> u32 {
        self.trim_end().parse().unwrap()
    }
    fn to_u64(&self) -> u64 {
        self.trim_end().parse().unwrap()
    }
    fn to_f64(&self) -> f64 {
        self.trim_end().parse().unwrap()
    }
    fn to_i128(&self) -> i128 {
        self.trim_end().parse().unwrap()
    }
}
impl ToNumber for usize {
    fn to_u32(&self) -> u32 {
        self.to_string().parse().unwrap()
    }
    fn to_u64(&self) -> u64 {
        self.to_string().parse().unwrap()
    }
    fn to_f64(&self) -> f64 {
        self.to_string().parse().unwrap()
    }
    fn to_i128(&self) -> i128 {
        self.to_string().parse().unwrap()
    }
}
//È PARI?                           fn is_even(&self) -> bool;
pub trait Even {
    fn is_even(&self) -> bool;
}
impl Even for u32 {
    fn is_even(&self) -> bool {
        if self % 2 == 0 {
            return true;
        } else {
            false
        }
    }
}
impl Even for i64 {
    fn is_even(&self) -> bool {
        if self % 2 == 0 {
            return true;
        } else {
            false
        }
    }
}


//SAVE AS CSV
pub trait SaveAny<T> {
    fn save_as_csv(&self) -> Result<(), Box<dyn Error>>;
}

impl<T> SaveAny<T> for Vec<T>where
    T:serde::Serialize{
    fn save_as_csv(&self) -> Result<(), Box<dyn Error>> {
        println!("Name the file:");
        let file_name = (String::new().input().replace(".csv", "") + ".csv").to_string();
        let mut wtr = Writer::from_path(file_name).unwrap();
        for i in 0..self.len() {
            wtr.serialize(&self[i])?;
        }
        Ok(())
    }

}
impl SaveAny<T> for String {
    fn save_as_csv(&self) -> Result<(), Box<dyn Error>> {
        println!("Name the file:");
        let file_name = (String::new().input().replace(".csv", "") + ".csv").to_string();
        let mut wtr = Writer::from_path(file_name).unwrap();
        wtr.serialize(&self)?;
        Ok(())
        
    }
}


//DA INPUT A STRINGA                fn input(&mut self) -> String;
pub trait Input {
    fn input(&mut self) -> String;
}
impl Input for String {
    fn input(&mut self) -> String {
        let mut y = String::new();
        io::stdin()
            .read_line(&mut y)
            .expect("Errore nella lettura dell'input");
        *self = y.trim_end().to_string();
        self.to_string()
    }
}

//DA INPUT A STRINGA ALFABETICO     fn input_alphabetic(&mut self) -> String;
pub trait InputToAlphabet {
    fn input_alphabetic(&mut self) -> String;
}
impl InputToAlphabet for String {
    fn input_alphabetic(&mut self) -> String {
        loop {
            let mut x = String::new();
            io::stdin()
                .read_line(&mut x)
                .expect("Errore nella lettura dell'input");
            *self = x.trim_end().to_string();
            if self.is_alphabetic() {
                return self.to_string();
            } else {
                println!("Invalid input!");
                continue;
            }
        }
    }
}

//DA INPUT A NUMERO              fn input_to_u32(&mut self) -> u32;
pub trait InputToNumber {
    fn input_to_u32(&mut self) -> u32;
    fn input_to_u64(&mut self) -> u64;
    fn input_to_f64(&mut self) -> f64;
    fn input_to_i128(&mut self) -> i128;
}
impl InputToNumber for String {
    fn input_to_u32(&mut self) -> u32 {
        loop {
            let mut x = String::new();
            io::stdin()
                .read_line(&mut x)
                .expect("Errore nella lettura dell'input");
            *self = x.trim_end().to_string();
            if self.is_number() {
                return self.to_u32();
            } else {
                println!("Invalid input!");
            }
        }
    }
    fn input_to_u64(&mut self) -> u64 {
        loop {
            let mut x = String::new();
            io::stdin()
                .read_line(&mut x)
                .expect("Errore nella lettura dell'input");
            *self = x.trim_end().to_string();
            if self.is_number() {
                return self.to_u64();
            } else {
                println!("Invalid input!");
            }
        }
    }
    fn input_to_f64(&mut self) -> f64 {
        loop {
            let mut x = String::new();
            io::stdin()
                .read_line(&mut x)
                .expect("Errore nella lettura dell'input");
            *self = x.trim_end().to_string();
            if self.is_number() {
                return self.to_f64();
            } else {
                println!("Invalid input!");
            }
        }
    }
    fn input_to_i128(&mut self) -> i128 {
        loop {
            let mut x = String::new();
            io::stdin()
                .read_line(&mut x)
                .expect("Errore nella lettura dell'input");
            *self = x.trim_end().to_string();
            if self.is_number() {
                return self.to_i128();
            } else {
                println!("Invalid input!");
            }
        }
    }
}

//SCOMPONI STRINGA IN STRINGHE      fn string_to_slices(&self)-> Vec<String>;
pub trait StringToSlices {
    fn string_to_slices(&self)-> Vec<String>;
}
impl StringToSlices for String {
    fn string_to_slices(&self) -> Vec<String> {

    let neword = self
        .replace(",", " , ")
        .replace("'", "' ")
        .replace("?", " ? ");

    let vec: Vec<String> = neword
        .trim_end()
        .split_whitespace()
        .map(String::from)
        .collect();

    return vec;
}
}