rok-utils 0.2.3

Laravel/AdonisJS-inspired utility helpers for the Rok ecosystem
Documentation
use rok_utils::str::Str;

#[test]
fn string_case_conversions() {
    assert_eq!(rok_utils::to_camel_case("hello_world"), "helloWorld");
    assert_eq!(rok_utils::to_camel_case("foo_bar_baz"), "fooBarBaz");
    assert_eq!(rok_utils::to_camel_case("TestV2"), "testV2");

    assert_eq!(rok_utils::to_snake_case("helloWorld"), "hello_world");
    assert_eq!(rok_utils::to_snake_case("XMLParser"), "xml_parser");
    assert_eq!(rok_utils::to_snake_case("TestV2"), "test_v2");

    assert_eq!(rok_utils::to_pascal_case("hello_world"), "HelloWorld");
    assert_eq!(rok_utils::to_pascal_case("helloWorld"), "HelloWorld");

    assert_eq!(rok_utils::to_kebab_case("helloWorld"), "hello-world");
    assert_eq!(rok_utils::to_kebab_case("HelloWorld"), "hello-world");

    assert_eq!(rok_utils::to_screaming_snake("helloWorld"), "HELLO_WORLD");

    assert_eq!(rok_utils::to_dot_case("hello world"), "hello.world");
    assert_eq!(rok_utils::to_title_case("hello world"), "Hello World");
    assert_eq!(rok_utils::to_sentence_case("HELLO WORLD"), "hello world");
    assert_eq!(rok_utils::to_no_case("HelloWorld"), "hello world");

    assert_eq!(rok_utils::to_upper("hello"), "HELLO");
    assert_eq!(rok_utils::to_lower("HELLO"), "hello");

    assert_eq!(rok_utils::ucfirst("hello"), "Hello");
    assert_eq!(rok_utils::lcfirst("Hello"), "hello");

    assert_eq!(rok_utils::invert_case("Hello"), "hELLO");
}

#[test]
fn string_transform() {
    assert_eq!(rok_utils::slug("Hello World!", '-'), "hello-world!");
    assert_eq!(rok_utils::slug("Test V2", '_'), "test_v2");

    assert_eq!(rok_utils::truncate("hello world", 5), "he...");
    assert_eq!(rok_utils::truncate("hi", 10), "hi");

    assert_eq!(rok_utils::squish("  hello   world  "), "hello world");

    assert_eq!(rok_utils::mask("hello world", '*', 6), "hello *****");

    assert_eq!(rok_utils::wrap("world", "[", "]"), "[world]");
    assert_eq!(rok_utils::unwrap("[world]", "[", "]"), "world");

    assert_eq!(rok_utils::pad_left("hello", 10, '-'), "-----hello");
    assert_eq!(rok_utils::pad_right("hello", 10, '-'), "hello-----");
    assert_eq!(rok_utils::pad_both("hello", 10, '-'), "--hello---");

    assert_eq!(rok_utils::repeat("ab", 3), "ababab");
    assert_eq!(rok_utils::reverse("hello"), "olleh");

    assert_eq!(
        rok_utils::replace_first("hello world", "world", "rust"),
        "hello rust"
    );
    assert_eq!(
        rok_utils::replace_last("hello hello hello", "hello", "rust"),
        "hello hello rust"
    );

    assert_eq!(rok_utils::finish("hello", ","), "hello,");
    assert_eq!(rok_utils::finish("hello,", ","), "hello,");

    assert_eq!(rok_utils::ensure_start("hello", ">"), ">hello");
    assert_eq!(rok_utils::ensure_start(">hello", ">"), ">hello");
}

#[test]
fn string_inspect() {
    assert!(!rok_utils::is_empty("hello"));
    assert!(rok_utils::is_empty("  "));

    assert!(rok_utils::is_ascii("hello"));
    assert!(!rok_utils::is_ascii("hello 世界"));

    assert!(rok_utils::is_alphanumeric("abc123"));
    assert!(!rok_utils::is_alphanumeric("abc!"));

    assert!(rok_utils::is_url("https://example.com"));
    assert!(!rok_utils::is_url("not-a-url"));

    assert_eq!(rok_utils::length("hello"), 5);
    assert_eq!(rok_utils::word_count("hello world"), 2);

    assert_eq!(rok_utils::char_at("hello", 0), Some('h'));
    assert_eq!(rok_utils::char_at("hello", 5), None);

    assert_eq!(rok_utils::position("hello world", "world"), Some(6));
    assert_eq!(rok_utils::position("hello", "x"), None);

    assert_eq!(rok_utils::substr_count("hello hello", "hello"), 2);

    assert!(rok_utils::starts_with("hello", "hel"));
    assert!(rok_utils::ends_with("hello", "lo"));
    assert!(rok_utils::contains("hello world", "world"));
    assert!(rok_utils::contains_all("hello", &["hel", "lo"]));
    assert!(rok_utils::doesnt_contain("hello", "x"));
}

#[test]
fn string_pluralize() {
    assert_eq!(rok_utils::pluralize("user"), "users");
    assert_eq!(rok_utils::pluralize("box"), "boxes");
    assert_eq!(rok_utils::pluralize("category"), "categories");
    assert_eq!(rok_utils::pluralize("leaf"), "leaves");
    assert_eq!(rok_utils::pluralize("cactus"), "cacti");
    assert_eq!(rok_utils::pluralize("day"), "days");
}

#[test]
fn string_pretty_duration() {
    assert_eq!(rok_utils::pretty_duration(500), "500ns");
    assert_eq!(rok_utils::pretty_duration(5000), "5μs");
    assert_eq!(rok_utils::pretty_duration(5_000_000), "5ms");
    assert_eq!(rok_utils::pretty_duration(5_000_000_000), "5s");
    assert_eq!(rok_utils::pretty_duration(300_000_000_000), "5m");
}

#[test]
fn string_base64() {
    let encoded = rok_utils::to_base64("hello");
    assert_eq!(encoded, "aGVsbG8=");
}

#[test]
fn fluent_builder_basic() {
    let result = Str::of("  Hello World  ").trim().snake().value();
    assert_eq!(result, "hello_world");
}

#[test]
fn fluent_builder_chain() {
    let result = Str::of("welcome").trim().lower().kebab().value();
    assert_eq!(result, "welcome");
}

#[test]
fn fluent_builder_conditional() {
    let result = Str::of("").when_empty(|s| s.append("default")).value();
    assert_eq!(result, "default");

    let result = Str::of("hello").when_empty(|s| s.append("default")).value();
    assert_eq!(result, "hello");

    let result = Str::of("hello world")
        .when_contains("world", |s| s.wrap("[", "]"))
        .value();
    assert_eq!(result, "[hello world]");
}

#[test]
fn fluent_builder_tap() {
    let mut seen = String::new();
    let _ = Str::of("test").tap(|s| seen.push_str(s));
    assert_eq!(seen, "test");
}

#[test]
fn fluent_builder_pipe() {
    let result = Str::of("hello").pipe(|s| s.to_uppercase()).value();
    assert_eq!(result, "HELLO");
}