tailwag_utils 0.3.0

A collection of assorted utility functions / traits. Part of the tailwag stack.
Documentation
pub fn to_snake_case(input: &str) -> String {
    let chars = input.chars();
    let mut output = String::new();
    let mut prev: Option<char> = None;
    for char in chars {
        if char.is_uppercase() && prev.map(|prev_char| prev_char.is_lowercase()).unwrap_or(false) {
            output.push('_');
        }
        if char.is_uppercase() {
            for char in char.to_lowercase() {
                output.push(char);
            }
        } else {
            output.push(char);
        }
        prev.replace(char);
    }
    output
}

pub trait ToSnakeCase {
    fn to_snake_case(&self) -> String;
}

impl ToSnakeCase for &str {
    fn to_snake_case(&self) -> String {
        to_snake_case(self)
    }
}
impl ToSnakeCase for String {
    fn to_snake_case(&self) -> String {
        to_snake_case(self)
    }
}

#[cfg(test)]
mod tests {
    use super::to_snake_case;

    #[test]
    fn to_camel_case_converts() {
        assert_eq!(to_snake_case("FoodTruck"), "food_truck");
        assert_eq!(to_snake_case("foodTruck"), "food_truck");
        assert_eq!(to_snake_case("FOodTRUck"), "food_truck");
        assert_eq!(to_snake_case("foodTruck"), "food_truck");
        assert_eq!(to_snake_case("foodtruck"), "foodtruck");
        assert_eq!(to_snake_case("_food_truck"), "_food_truck");
        assert_eq!(to_snake_case("FOOD_TRUCK"), "food_truck");
        assert_eq!(to_snake_case("_FOOD_TRUCK"), "_food_truck");
    }
}