Skip to content

Commit f4135f6

Browse files
authored
Merge pull request #14 from anirudhb/null-safety
Migrate to null safety
2 parents df940e3 + 74f8a36 commit f4135f6

14 files changed

Lines changed: 145 additions & 128 deletions

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# CHANGELOG
22

3+
## 0.4.0-nullsafety.0
4+
- Migrate to null safety
5+
36
## 0.3.0
47
- Improve search results on weighted search to combine scores from all keys
58
- Improve search results on single-keyed search, making it consistent with non-weighted search

analysis_options.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ include: package:pedantic/analysis_options.yaml
55
analyzer:
66
strong-mode:
77
implicit-casts: false
8-
exclude:
9-
- example/**/*.dart
10-
- test/**/*.dart
118
linter:
129
rules:
1310
- public_member_api_docs

example/pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ authors:
77
environment:
88
sdk: '>=2.0.0 <3.0.0'
99

10+
publish_to: none
11+
1012
dependencies:
1113
fuzzy:
1214
path: ../

lib/bitap/bitap.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'package:latinize/latinize.dart';
2-
32
import '../data/fuzzy_options.dart';
43
import 'bitap_pattern_alphabet.dart' as pa;
54
import 'bitap_search.dart';
@@ -18,7 +17,7 @@ import 'data/match_index.dart';
1817
/// work with bitwise operations, which are extremely fast.
1918
class Bitap {
2019
/// Instantiates a bitap, given options
21-
Bitap(String pattern, {FuzzyOptions options}) : options = options {
20+
Bitap(String pattern, {required FuzzyOptions options}) : options = options {
2221
this.pattern = options.isCaseSensitive ? pattern : pattern.toLowerCase();
2322
this.pattern =
2423
options.shouldNormalize ? latinize(this.pattern) : this.pattern;
@@ -31,7 +30,7 @@ class Bitap {
3130
final FuzzyOptions options;
3231

3332
/// The pattern to search for
34-
String pattern;
33+
late String pattern;
3534

3635
/// The laphabet derived from the pattern
3736
Map<String, int> patternAlphabet = {};

lib/bitap/bitap_matched_indices.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ import 'data/match_index.dart';
22

33
/// Retrieve all matched indexes given a mask and minimum length
44
List<MatchIndex> matchedIndices(List<int> matchmask, int minMatchCharLength) {
5-
matchmask ??= [];
6-
minMatchCharLength ??= 1;
7-
85
final matchedIndices = <MatchIndex>[];
96
var start = -1;
107
var end = -1;

lib/bitap/bitap_regex_search.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ final Pattern SPECIAL_CHARS_REGEX =
88
/// Execute a bitap regex search
99
MatchScore bitapRegexSearch(
1010
String text, String pattern, Pattern tokenSeparator) {
11-
tokenSeparator ??= RegExp(r' +');
12-
1311
final regex = RegExp(pattern
1412
.replaceAll(SPECIAL_CHARS_REGEX, r'\$&')
1513
.replaceAll(tokenSeparator, '|'));

lib/bitap/data/match_score.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import 'match_index.dart';
44
class MatchScore {
55
/// Instantiates a match with score and matched locations
66
MatchScore({
7-
this.score,
8-
this.isMatch,
7+
required this.score,
8+
required this.isMatch,
99
this.matchedIndices = const [],
1010
});
1111

lib/data/fuzzy_options.dart

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import 'package:meta/meta.dart';
2-
31
import 'result.dart';
42

53
/// Represents a weighted getter of an item
64
class WeightedKey<T> {
75
/// Instantiates it
86
WeightedKey({
9-
@required this.name,
10-
@required this.getter,
11-
@required this.weight,
7+
required this.name,
8+
required this.getter,
9+
required this.weight,
1210
}) : assert(weight > 0, 'Weight should be positive and non-zero');
1311

1412
/// Name of this getter
@@ -23,7 +21,7 @@ class WeightedKey<T> {
2321
final double weight;
2422
}
2523

26-
/// Sorter function
24+
/// Function used to sort results.
2725
typedef SorterFn<T> = int Function(Result<T> a, Result<T> b);
2826

2927
int _defaultSortFn<T>(Result<T> a, Result<T> b) => a.score.compareTo(b.score);
@@ -39,13 +37,13 @@ class FuzzyOptions<T> {
3937
this.threshold = 0.6,
4038
this.maxPatternLength = 32,
4139
this.isCaseSensitive = false,
42-
Pattern tokenSeparator,
43-
this.minTokenCharLength = 1,
40+
Pattern? tokenSeparator,
4441
this.findAllMatches = false,
42+
this.minTokenCharLength = 1,
4543
this.minMatchCharLength = 1,
4644
List<WeightedKey<T>> keys = const [],
4745
this.shouldSort = true,
48-
SorterFn<T> sortFn,
46+
SorterFn<T>? sortFn,
4947
this.tokenize = false,
5048
this.matchAllTokens = false,
5149
this.verbose = false,
@@ -113,24 +111,42 @@ class FuzzyOptions<T> {
113111
/// characters before searching.
114112
final bool shouldNormalize;
115113

116-
/// Merge two options instances. Useful for overriding just some options.
117-
FuzzyOptions<T> mergeWith(FuzzyOptions<T> options) => FuzzyOptions(
118-
location: options?.location ?? location,
119-
distance: options?.distance ?? distance,
120-
threshold: options?.threshold ?? threshold,
121-
maxPatternLength: options?.maxPatternLength ?? maxPatternLength,
122-
isCaseSensitive: options?.isCaseSensitive ?? isCaseSensitive,
123-
tokenSeparator: options?.tokenSeparator ?? tokenSeparator,
124-
minTokenCharLength: options?.minTokenCharLength ?? minTokenCharLength,
125-
findAllMatches: options?.findAllMatches ?? findAllMatches,
126-
minMatchCharLength: options?.minMatchCharLength ?? minMatchCharLength,
127-
keys: options?.keys ?? keys,
128-
shouldSort: options?.shouldSort ?? shouldSort,
129-
sortFn: options?.sortFn ?? sortFn,
130-
tokenize: options?.tokenize ?? tokenize,
131-
matchAllTokens: options?.matchAllTokens ?? matchAllTokens,
132-
verbose: options?.verbose ?? verbose,
133-
shouldNormalize: options?.shouldNormalize ?? shouldNormalize,
114+
/// Copy these options with some modifications.
115+
FuzzyOptions<T> copyWith({
116+
int? location,
117+
int? distance,
118+
double? threshold,
119+
int? maxPatternLength,
120+
bool? isCaseSensitive,
121+
Pattern? tokenSeparator,
122+
bool? findAllMatches,
123+
int? minTokenCharLength,
124+
int? minMatchCharLength,
125+
List<WeightedKey<T>>? keys,
126+
bool? shouldSort,
127+
SorterFn<T>? sortFn,
128+
bool? tokenize,
129+
bool? matchAllTokens,
130+
bool? verbose,
131+
bool? shouldNormalize,
132+
}) =>
133+
FuzzyOptions(
134+
location: location ?? this.location,
135+
distance: distance ?? this.distance,
136+
threshold: threshold ?? this.threshold,
137+
maxPatternLength: maxPatternLength ?? this.maxPatternLength,
138+
isCaseSensitive: isCaseSensitive ?? this.isCaseSensitive,
139+
tokenSeparator: tokenSeparator ?? this.tokenSeparator,
140+
findAllMatches: findAllMatches ?? this.findAllMatches,
141+
minTokenCharLength: minTokenCharLength ?? this.minTokenCharLength,
142+
minMatchCharLength: minMatchCharLength ?? this.minMatchCharLength,
143+
keys: keys ?? this.keys,
144+
shouldSort: shouldSort ?? this.shouldSort,
145+
sortFn: sortFn ?? this.sortFn,
146+
tokenize: tokenize ?? this.tokenize,
147+
matchAllTokens: matchAllTokens ?? this.matchAllTokens,
148+
verbose: verbose ?? this.verbose,
149+
shouldNormalize: shouldNormalize ?? this.shouldNormalize,
134150
);
135151

136152
static List<WeightedKey<T>> _normalizeWeights<T>(List<WeightedKey<T>> keys) {

lib/data/result.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import '../bitap/data/match_index.dart';
55
class Searchers {
66
/// Instantiates it
77
Searchers({
8-
this.tokenSearchers,
9-
this.fullSearcher,
8+
required this.tokenSearchers,
9+
required this.fullSearcher,
1010
});
1111

1212
/// All searchers, if tokenized
@@ -24,8 +24,8 @@ class Searchers {
2424
class ResultsAndWeights<T> {
2525
/// Instantiates it
2626
ResultsAndWeights({
27-
this.results,
28-
this.weights,
27+
required this.results,
28+
required this.weights,
2929
});
3030

3131
/// The list of results
@@ -39,7 +39,7 @@ class ResultsAndWeights<T> {
3939
class Result<T> {
4040
/// Instantiates it
4141
Result({
42-
this.item,
42+
required this.item,
4343
this.matches = const [],
4444
this.score = 0,
4545
});
@@ -62,11 +62,11 @@ class ResultDetails<T> {
6262
/// Instantiates it
6363
ResultDetails({
6464
this.key = '',
65-
this.arrayIndex,
66-
this.value,
67-
this.score,
68-
this.matchedIndices,
69-
this.nScore,
65+
required this.arrayIndex,
66+
required this.value,
67+
required this.score,
68+
required this.matchedIndices,
69+
this.nScore = 0,
7070
});
7171

7272
/// Key ([WeightedKey.name]) used to create this

lib/fuzzy.dart

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export 'data/fuzzy_options.dart';
1818
class Fuzzy<T> {
1919
/// Instantiates it given a list of strings to look into, and options
2020
Fuzzy(
21-
List<T> list, {
22-
FuzzyOptions<T> options,
21+
List<T>? list, {
22+
FuzzyOptions<T>? options,
2323
}) : list = list ?? [],
2424
options = options ?? FuzzyOptions<T>();
2525

@@ -117,7 +117,7 @@ class Fuzzy<T> {
117117
final key = options.keys[j].name;
118118
final value = options.keys[j].getter(item);
119119

120-
final weight = 1.0 - options.keys[j].weight ?? 0.0;
120+
final weight = 1.0 - options.keys[j].weight;
121121
weights.update(key, (_) => weight, ifAbsent: () => weight);
122122

123123
_analyze(
@@ -138,18 +138,16 @@ class Fuzzy<T> {
138138

139139
List<Result<T>> _analyze({
140140
String key = '',
141-
String value,
142-
T record,
143-
int index,
141+
required String value,
142+
required T record,
143+
required int index,
144144
List<Bitap> tokenSearchers = const [],
145-
Bitap fullSearcher,
146-
List<Result<T>> results,
147-
Map<int, Result<T>> resultMap,
145+
required Bitap fullSearcher,
146+
List<Result<T>> results = const [],
147+
Map<int, Result<T>> resultMap = const {},
148148
}) {
149-
results ??= <Result<T>>[];
150-
resultMap ??= <int, Result<T>>{};
151149
// Check if the texvaluet can be searched
152-
if (value == null) {
150+
if (value.isEmpty) {
153151
return [];
154152
}
155153

@@ -282,7 +280,7 @@ class Fuzzy<T> {
282280

283281
// We don't use 0 so that the weight differences don't get zeroed out
284282
final score = match.score == 0.0 ? 0.001 : match.score;
285-
final nScore = score * weight;
283+
final nScore = score * (weight ?? 1.0);
286284

287285
match.nScore = nScore;
288286
currScore *= nScore;

0 commit comments

Comments
 (0)