# text-statistics

[![crates.io](https://img.shields.io/crates/v/text-statistics.svg)](https://crates.io/crates/text-statistics)
[![Documentation](https://docs.rs/text-statistics/badge.svg)](https://docs.rs/text-statistics)

Comprehensive text statistics: word, sentence, and character counts, average
word length, average sentence length, estimated reading time, and a
lexile-like difficulty estimate — pure Rust, **zero dependencies**,
deterministic.

These are the same measurements the [**BeLikeNative**](https://belikenative.com/)
AI writing assistant surfaces while you write, packaged as a small,
embeddable library you can drop into editors, CLIs, static-site generators,
or build pipelines.

## Why

Word counts, sentence counts, and reading-time estimates are the backbone of
nearly every writing tool. The math is small and public — there is no reason
to shell out to a paid API or pull in a heavy NLP dependency just to get
them. This crate does the whole job in a single dependency-free file and
adds a calibrated, lexile-like difficulty score on top.

## Install

```toml
[dependencies]
text-statistics = "0.1"
```

## Quick start

```rust
use text_statistics::{stats, Difficulty};

let s = stats("The cat sat on the mat. It was a good day for a nap.");
assert_eq!(s.words, 14);
assert_eq!(s.sentences, 2);
assert_eq!(s.difficulty_band(), Difficulty::Easy);
println!("~{} min read", s.estimated_reading_minutes);
```

## What you get

`stats(&str)` returns a `TextStats` with:

| field                       | meaning                                                  |
| --------------------------- | -------------------------------------------------------- |
| `words`                     | word-token count (contractions count as one)             |
| `sentences`                 | sentence-ending units (`. ! ?`)                          |
| `characters`                | total Unicode scalars                                    |
| `characters_no_spaces`      | total scalars minus whitespace                           |
| `avg_word_length`           | mean letters per word (digits excluded)                  |
| `avg_sentence_length`       | mean words per sentence                                  |
| `estimated_reading_seconds` | reading time at 200 wpm (min 1s for non-empty text)      |
| `estimated_reading_minutes` | ceiling of the above, min 1 for non-empty text           |
| `difficulty_score`          | 0–100 lexile-like blend of word/sentence length          |

`difficulty_band()` maps the score to `Easy` / `Medium` / `Hard`.

## Tuning

Reading speed, the easy/hard word-length thresholds, and the hard
sentence-length threshold are all `pub const`. Re-export them or copy the
`stats` function to recalibrate for your corpus.

## Determinism

The same input always yields the same output — there is no randomness, no
network, and no global state. Safe to call from multiple threads.

## License

MIT. Built for [BeLikeNative](https://belikenative.com/).
