1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! The single tokenizer shared by index build and query parsing.
//!
//! Both sides of a BM25 lookup must agree on what a term *is*; if the builder
//! and the query parser tokenize differently, a query can never match a
//! document that plainly contains its words and nothing reports an error. That
//! failure is silent, so the two sides are not allowed to have two
//! implementations: [`analyze`] is the only tokenizer in the retrieval lane.
//!
//! The character rule is the one `text_normalize()` already exposes to Cypher
//! users (`scalar_functions/string.rs`), so a caller can predict tokenization
//! from a function they can run: **`char::is_alphanumeric` is term content,
//! every other character is a separator, and content is lowercased with
//! `char::to_lowercase` (multi-char aware — `İ` lowercases to two chars).**
//! Unicode letters are content, so `Tromsø` is one token and accents survive.
//!
//! Consequences worth knowing before you rely on it:
//!
//! * There is **no CJK segmentation**. Han/Hiragana/Katakana are alphanumeric,
//! so a run of them with no intervening separator becomes a single term.
//! CJK retrieval needs a segmenting analyzer, which v1 does not ship.
//! * `it's` tokenizes as `it` + `s`, and `3.14` as `3` + `14`; the apostrophe
//! and the period are separators like any other punctuation.
use Cow;
/// Tokenize `text` into lowercased terms. Lazy: nothing is allocated for a
/// token that is already lowercase (the overwhelmingly common case), which is
/// why the item type is [`Cow`].
/// Iterator returned by [`analyze`].
/// Per-*character* lowercasing, deliberately not `str::to_lowercase`: the
/// latter applies the Greek final-sigma rule (`Σ` → `ς` at a word end), which
/// would make a term's normalization depend on its position in the source
/// text. `text_normalize()` lowercases per char, and the two must agree.
/// Whether lowercasing this char yields exactly itself.