Skip to content

API Reference

text-statistics exposes one entry point — stats — plus the TextStats / Difficulty types and the tunable constants the difficulty estimate is built from. All counts are u64; averages and durations are f64. No traits to implement, no features to enable.

Constants

The difficulty-estimate coefficients and reading-speed reference. They are pub so callers can calibrate against their own corpora.

/// Average adult reading speed, words per minute.
pub const WORDS_PER_MINUTE: f64          = 200.0;
/// Characters per word at grade-5 level (below = "easy").
pub const EASY_AVG_WORD_LENGTH: f64      = 4.5;
/// Characters per word above which text is "difficult" (~grade 11+).
pub const HARD_AVG_WORD_LENGTH: f64      = 6.5;
/// Words per sentence above which a sentence is "hard to follow".
pub const HARD_AVG_SENTENCE_LENGTH: f64  = 20.0;

stats

pub fn stats(text: &str) -> TextStats

Compute the full TextStats bundle for text. A single pass produces every field. Empty input yields all-zero counts (and zero difficulty). The function is total: it never panics.

use text_statistics::stats;

let s = stats("Hello world. Short sentence.");
assert_eq!(s.words, 4);
assert_eq!(s.sentences, 2);
assert!(s.estimated_reading_seconds >= 1.0);

TextStats

pub struct TextStats {
    pub words: u64,
    pub sentences: u64,
    pub characters: u64,
    pub characters_no_spaces: u64,
    pub avg_word_length: f64,
    pub avg_sentence_length: f64,
    pub estimated_reading_seconds: f64,
    pub estimated_reading_minutes: u64,
    pub difficulty_score: f64,
}
field meaning
words word tokens (contractions whole; punctuation dropped)
sentences ., !, ? count; a word-only fragment counts as 1
characters total Unicode scalar values, whitespace included
characters_no_spaces characters excluding ASCII whitespace
avg_word_length letters per word (0.0 if no words; digits excluded)
avg_sentence_length words / sentences (0.0 if no sentences)
estimated_reading_seconds (words / 200) * 60, minimum 1.0 for non-empty input
estimated_reading_minutes whole minutes, rounded up, minimum 1 for non-empty input
difficulty_score 0–100 blend of word-length and sentence-length signals

difficulty_band

impl TextStats {
    pub fn difficulty_band(&self) -> Difficulty
}

Map the continuous difficulty_score to a coarse band. Easy < 33, Medium 33–66, Hard >= 66.

use text_statistics::{stats, Difficulty};

assert_eq!(stats("The cat sat.").difficulty_band(),  Difficulty::Easy);
assert_eq!(stats("...long dense prose...").difficulty_band(), Difficulty::Hard);

Difficulty

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Difficulty {
    Easy,    // short words, short sentences — early-grade reading
    Medium,  // typical adult prose
    Hard,    // long words or long sentences — advanced reading
}

A coarse band derived from TextStats::difficulty_score. Derives Debug, Clone, Copy, PartialEq, and Eq so it compares and copies cheaply.