Line data Source code
1 : // Copyright 2026 The Authors.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // https://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : /// A detected language with its confidence in `[0.0, 1.0]`.
16 : final class LanguageGuess {
17 : /// ISO 639-1 language code (e.g. `"en"`, `"hu"`). Matches the code set
18 : /// used by `betto_lexical`'s `Stopwords` enum.
19 : final String code;
20 :
21 : /// Confidence in `[0.0, 1.0]`.
22 : ///
23 : /// This is a relative score within the candidate set that was compared,
24 : /// not a calibrated probability — the same input text can report a
25 : /// different confidence depending on how many (and which) languages it
26 : /// was compared against. See `NgramBackend` for the exact formula.
27 : final double confidence;
28 :
29 : /// Creates a guess for [code] with the given [confidence].
30 6 : const LanguageGuess(this.code, this.confidence);
31 :
32 1 : @override
33 3 : String toString() => 'LanguageGuess($code, $confidence)';
34 :
35 3 : @override
36 : bool operator ==(Object other) =>
37 3 : other is LanguageGuess &&
38 9 : other.code == code &&
39 9 : other.confidence == confidence;
40 :
41 1 : @override
42 3 : int get hashCode => Object.hash(code, confidence);
43 : }
44 :
45 : /// The result of [LanguageDetector.detect].
46 : ///
47 : /// Always one of [Detected] or [Undetermined] — exhaustively matchable with
48 : /// a `switch`.
49 : sealed class DetectionResult {}
50 :
51 : /// A language was identified with confidence at or above the detector's
52 : /// `minConfidence` threshold.
53 : final class Detected extends DetectionResult {
54 : /// The highest-confidence guess.
55 : final LanguageGuess best;
56 :
57 : /// All scored guesses, ranked by descending confidence (including [best]
58 : /// as the first element).
59 : final List<LanguageGuess> ranked;
60 :
61 : /// Creates a result naming [best] as the detected language, alongside the
62 : /// full [ranked] list it was chosen from.
63 2 : Detected(this.best, this.ranked);
64 :
65 1 : @override
66 3 : String toString() => 'Detected($best, ranked: $ranked)';
67 : }
68 :
69 : /// No language met the detector's `minConfidence` threshold.
70 : final class Undetermined extends DetectionResult {
71 : /// Whatever candidates were scored, ranked by descending confidence. May
72 : /// be empty (e.g. for empty/whitespace-only or script-less input).
73 : final List<LanguageGuess> ranked;
74 :
75 : /// Creates a result carrying the scored-but-inconclusive [ranked] list.
76 2 : Undetermined(this.ranked);
77 :
78 1 : @override
79 2 : String toString() => 'Undetermined(ranked: $ranked)';
80 : }
|