ncase 0.1.1

Enforce a case style
Documentation
use rand::rngs::SmallRng;
use rand::{Rng, SeedableRng};

/// Returns the case-randomised equivalent of the string slice as a new [`String`].
pub fn to_randomcase(s: &str) -> String {
    let mut rng = SmallRng::from_entropy();
    s.chars()
        .map(|c| {
            if rng.gen() {
                c.to_lowercase().to_string()
            } else {
                c.to_uppercase().to_string()
            }
        })
        .collect()
}

/// Returns the `Title Case` equivalent of the string slice as a new [`String`].
pub fn to_titlecase(s: &str) -> String {
    to_txcase(s, char::to_uppercase, char::to_lowercase)
}

/// Returns the `tOGGLE cASE` equivalent of the string slice as a new [`String`].
pub fn to_togglecase(s: &str) -> String {
    to_txcase(s, char::to_lowercase, char::to_uppercase)
}

fn to_txcase<F1, F2, I1, I2>(s: &str, first_fn: F1, rest_fn: F2) -> String
where
    F1: FnOnce(char) -> I1,
    F2: Fn(char) -> I2,
    I1: Iterator<Item = char>,
    I2: Iterator<Item = char>,
{
    let mut cs = s.chars();
    match cs.next() {
        Some(c) => first_fn(c).chain(cs.flat_map(rest_fn)).collect(),
        None => String::new(),
    }
}