com.xlrit.gears.base.choice.Choices Maven / Gradle / Ivy
package com.xlrit.gears.base.choice;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.xlrit.gears.base.util.Range;
public interface Choices {
String FILTER_NONE = null;
Kind kind();
int count();
default Optional find(String value) {
return items().filter(choice -> value.equals(choice.getValue())).findAny();
}
default boolean contains(String value) {
return find(value).isPresent();
}
default Stream items() {
return items(FILTER_NONE, 0, Integer.MAX_VALUE);
}
default Stream items(String filter, int start, int count) {
return items()
.filter(filterToPredicate(filter))
.skip(start)
.limit(count);
}
default Stream items(String filter, Range range) {
int start = range != null ? range.getStart() : 0;
int count = range != null ? range.getCount() : Integer.MAX_VALUE;
return items(filter, start, count);
}
static Predicate filterToPredicate(String filter) {
if (filter == null || filter.isBlank()) return choice -> true;
SearchParts searchParts = SearchParts.extract(filter, "regex");
return switch (searchParts.mode()) {
case "equals" -> labelEquals(searchParts.searchText());
case "starts" -> labelStarts(searchParts.searchText());
case "contains" -> labelContains(searchParts.searchText());
case "regex" -> labelRegex(searchParts.searchText());
default -> throw new IllegalArgumentException("Unrecognized mode '" + searchParts.mode() + "'");
};
}
static Predicate labelEquals(String searchText) {
return choice -> choice.getLabel().equalsIgnoreCase(searchText);
}
static Predicate labelStarts(String searchText) {
String searchLower = searchText.toLowerCase();
return choice -> choice.getLabel().toLowerCase().startsWith(searchLower);
}
static Predicate labelContains(String searchText) {
String searchLower = searchText.toLowerCase();
return choice -> choice.getLabel().toLowerCase().contains(searchLower);
}
static Predicate labelRegex(String searchText) {
String regex = Arrays.stream(searchText.split("\\s+")).map(Pattern::quote).collect(Collectors.joining("|"));
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
return choice -> pattern.matcher(choice.getLabel()).find();
}
enum Kind {
STATIC,
DYNAMIC,
}
}