sentiment-basic 0.1.0

Simple, deterministic positive/negative word-count sentiment scoring with built-in word lists — pure, zero-dependency, no network.
Documentation
# sentiment-basic

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

Simple, deterministic positive/negative word-count sentiment scoring with
**built-in word lists**. Pure Rust, **zero dependencies**, no network, no
model downloads — the same lightweight signal the
[**BeLikeNative**](https://belikenative.com/) AI writing assistant uses for a
fast first-pass tone read.

## What this is

A **lexicon** scorer, not a machine-learning model. It counts matches against
two small, hand-curated lists of unambiguous positive and negative words and
reports the balance. That makes it:

- **fast** — microsecond-scale, suitable for hot paths and huge corpora;
- **fully deterministic** — identical input always yields identical output;
- **auditable** — the entire "model" is two `&[&str]` constants you can read;
- **offline** — no API keys, no network, no runtime downloads.

The trade-off is that it does **not** understand negation ("not good"),
sarcasm, intensifiers, or context. For nuanced analysis, pair it with a real
model. For a stable, inspectable baseline — word counts, dashboards, gating,
A/B signal — it is exactly right.

## Install

```toml
[dependencies]
sentiment-basic = "0.1"
```

## Quick start

```rust
use sentiment_basic::score;

let r = score("I love this bright happy day. It is awful and terrible though.");
println!("label:    {}", r.label());        // positive | negative | neutral
println!("net:      {}", r.net());          // i64, +positive - negative
println!("compare:  {:.2}", r.comparison()); // -1.0..=1.0
println!("pos share:{:.2}", r.positive_share()); // 0.0..=1.0
```

## API

`score(&str)` returns a `Sentiment`:

| field             | meaning                                                |
| ----------------- | ------------------------------------------------------ |
| `positive_hits`   | count of positive lexicon words matched                |
| `negative_hits`   | count of negative lexicon words matched                |
| `tokens`          | total word tokens scanned                              |
| `net()`           | `positive_hits - negative_hits` as `i64`               |
| `comparison()`    | `(pos - neg) / (pos + neg)`, in `-1.0..=1.0`           |
| `positive_share()`| fraction of polarity tokens that are positive          |
| `label()`         | `"positive"`, `"negative"`, or `"neutral"`             |

Matching is case-insensitive, whole-word, and punctuation-safe. The lexicons
are exported as `POSITIVE_WORDS` and `NEGATIVE_WORDS` if you want to extend
or inspect them.

## Determinism & safety

No randomness, no global state, no `unsafe`. Safe to call from multiple
threads. Empty input returns a zero-hit `"neutral"` result.

## License

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