# Module Structure

```
rok-utils/
├── Cargo.toml
├── src/
│   ├── lib.rs               ← Public re-exports, feature gates
│   ├── str/
│   │   ├── mod.rs           ← str::* top-level re-exports
│   │   ├── case.rs          ← Case conversions (snake, camel, pascal…)
│   │   ├── transform.rs     ← slug, truncate, excerpt, squish, wrap…
│   │   ├── inspect.rs       ← is_empty, starts_with, contains, word_count…
│   │   ├── fluent.rs        ← Str::of() builder (chainable API)
│   │   └── random.rs        ← random() — requires "random" feature
│   ├── arr/
│   │   ├── mod.rs
│   │   ├── ops.rs           ← map, filter, reduce, chunk, flatten…
│   │   ├── query.rs         ← first, last, find, where_in, pluck…
│   │   └── set.rs           ← unique, diff, intersect, merge…
│   ├── errors/
│   │   ├── mod.rs
│   │   ├── kinds.rs         ← RokError enum (all variants)
│   │   ├── context.rs       ← wrap_error, add_context, ResultExt trait
│   │   └── http.rs          ← HttpError with status codes (AdonisJS-style)
│   ├── data/
│   │   ├── mod.rs
│   │   ├── numbers.rs       ← format_number, format_currency, round…
│   │   ├── dates.rs         ← now, today, format, diff (needs "dates")
│   │   ├── hashing.rs       ← hash, verify, generate_token (needs "crypto")
│   │   └── ids.rs           ← uuid_v4, uuid_v7, ulid (needs "ids")
│   ├── fp/
│   │   ├── mod.rs
│   │   ├── compose.rs       ← pipe, compose, partial, tap
│   │   ├── lazy.rs          ← Lazy<T>, memoize, once
│   │   └── macros.rs        ← macro_rules! helpers
│   └── types/
│       ├── mod.rs
│       └── guards.rs        ← is_json, is_uuid, is_ulid, is_url…
├── tests/
│   ├── str_tests.rs
│   ├── arr_tests.rs
│   ├── error_tests.rs
│   └── proptest_suite.rs
└── benches/
    └── string_bench.rs
```

## Module Guidelines

- Each sub-module file should be `< 400 lines`
- All public functions must have doc comments with examples
- Feature-gated modules must use `#[cfg(feature = "...")]`
- Every module must have inline `#[cfg(test)]` tests