package uk.co.nickthecoder.feather.runtime;
import java.util.*;
final public class FeatherExtensions {
private FeatherExtensions() {
}
public static boolean isUpperCase(char c) {
return Character.isUpperCase(c);
}
public static boolean isLowerCase(char c) {
return Character.isLowerCase(c);
}
public static char toUpperCase(char c) {
return Character.toUpperCase(c);
}
public static char toLowerCase(char c) {
return Character.toLowerCase(c);
}
public static boolean isAlphabetic(char c) {
return Character.isAlphabetic(c);
}
public static boolean isDigit(char c) {
return Character.isDigit(c);
}
public static boolean isLetter(char c) {
return Character.isLetter(c);
}
public static boolean isLetterOrDigit(char c) {
return Character.isLetterOrDigit(c);
}
/**
* This is DIFFERENT from Java's Character.isWhiteSpace.
* Java considers 160 (non-breaking space) NOT to be whitespace.
* I've chosen for feather to go against this, and consider it to be whitespace.
* So Feather is consistent with Kotlin (and Unicode apparently), and IMHO common sense!
*/
public static boolean isWhitespace(char c) {
return Character.isWhitespace(c) || Character.isSpaceChar(c);
}
public static boolean isSpaceChar(char c) {
return Character.isSpaceChar(c);
}
public static String toString(char c) {
return Character.toString(c);
}
public static int size(String s) {
return s.length();
}
public static boolean isNotEmpty(String s) {
return !s.isEmpty();
}
public static boolean isNotBlank(String s) {
return !s.isBlank();
}
public static boolean isNullOrBlank(String s) {
return s == null || s.isBlank();
}
public static boolean isNullOrEmpty(String s) {
return s == null || s.isEmpty();
}
public static CharSequenceIterator iterator(CharSequence s) {
return new CharSequenceIterator(s);
}
@Deprecated // Use toInt instead.
public static int parseInt(double value) {
return (int) value;
}
public static int toInt(double value) {
return (int) value;
}
public static int toInt(float value) {
return (int) value;
}
public static int toInt(String str) {
return Integer.parseInt(str);
}
public static int toInt(String str, int defaultValue) {
try {
return Integer.parseInt(str);
} catch (Exception e) {
return defaultValue;
}
}
@Deprecated // Use toLong instead.
public static long parseLong(double value) {
return (long) value;
}
public static long toLong(double value) {
return (long) value;
}
public static long toLong(float value) {
return (long) value;
}
public static long toLong(String str) {
return Long.parseLong(str);
}
public static long toLong(String str, long defaultValue) {
try {
return Long.parseLong(str);
} catch (Exception e) {
return defaultValue;
}
}
@Deprecated // Use toFloat instead.
public static float parseFloat(String str) {
return Float.parseFloat(str);
}
public static float toFloat(String str) {
return Float.parseFloat(str);
}
public static float toFloat(String str, float defaultValue) {
try {
return Float.parseFloat(str);
} catch (Exception e) {
return defaultValue;
}
}
@Deprecated // Use toDouble instead.
public static double parseDouble(String str) {
return Double.parseDouble(str);
}
public static double toDouble(String str) {
return Double.parseDouble(str);
}
public static double toDouble(String str, double defaultValue) {
try {
return Double.parseDouble(str);
} catch (Exception e) {
return defaultValue;
}
}
public static String times(String str, int times) {
return String.valueOf(str).repeat(Math.max(0, times));
}
public static String times(char c, int times) {
return String.valueOf(c).repeat(Math.max(0, times));
}
public static List<String> splitLines(String str) {
return splitTerminator(str, "\n");
}
public static List<String> splitTerminator(String str, String regex) {
if (str.isEmpty()) {
return new ArrayList<>();
} else {
if (str.endsWith(regex)) {
return Arrays.asList(str.substring(0, str.length() - regex.length()).split(regex));
} else {
return Arrays.asList(str.split(regex));
}
}
}
public static CharRange rangeTo(char start, char endInclusive) {
return new CharRange(start, endInclusive);
}
public static CharRange until(char start, char endExclusive) {
return CharRange.exclusiveRange(start, endExclusive);
}
public static CharRange rangeUntil(char start, char endExclusive) {
return CharRange.exclusiveRange(start, endExclusive);
}
public static CharProgression downTo(char start, char endInclusive) {
return new CharProgression(start, endInclusive, -1);
}
/**
* Creates a CharRange from start to endInclusive if endInclusive >= start,
* otherwise it creates a downwards CharProgression (with step -1).
* Note, there is no similar method which uses an exclusive end.
*/
public static CharProgression to(char start, char endInclusive) {
if (endInclusive >= start) {
return new CharRange(start, endInclusive);
} else {
return new CharProgression(start, endInclusive, -1);
}
}
public static IntRange rangeTo(int start, int endInclusive) {
return new IntRange(start, endInclusive);
}
public static IntRange until(int start, int endExclusive) {
return IntRange.exclusiveRange(start, endExclusive);
}
public static IntRange rangeUntil(int start, int endExclusive) {
return IntRange.exclusiveRange(start, endExclusive);
}
public static IntProgression downTo(int start, int endInclusive) {
return new IntProgression(start, endInclusive, -1);
}
/**
* Creates an IntRange from start to endInclusive if endInclusive >= start,
* otherwise it creates a downwards IntProgression (with step -1).
* Note, there is no similar method which uses an exclusive end.
*/
public static IntProgression to(int start, int endInclusive) {
if (endInclusive >= start) {
return new IntRange(start, endInclusive);
} else {
return new IntProgression(start, endInclusive, -1);
}
}
public static LongRange rangeTo(long start, long endInclusive) {
return new LongRange(start, endInclusive);
}
public static LongRange until(long start, long endExclusive) {
return LongRange.exclusiveRange(start, endExclusive);
}
public static LongRange rangeUntil(long start, long endExclusive) {
return LongRange.exclusiveRange(start, endExclusive);
}
public static LongProgression downTo(long start, long endInclusive) {
return new LongProgression(start, endInclusive, -1L);
}
/**
* Creates an IntRange from start to endInclusive if endInclusive >= start,
* otherwise it creates a downwards IntProgression (with step -1).
* Note, there is no similar method which uses an exclusive end.
*/
public static LongProgression to(long start, int endInclusive) {
if (endInclusive >= start) {
return new LongRange(start, endInclusive);
} else {
return new LongProgression(start, endInclusive, -1L);
}
}
public static int barrelIndex(int size, int index) {
int remainder = index % size;
return remainder < 0 ? size + remainder : remainder;
}
public static boolean isNotEmpty(Collection<?> collection) {
return !collection.isEmpty();
}
public static boolean isNotEmpty(Map<?, ?> map) {
return !map.isEmpty();
}
public static boolean isNullOrEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
public static boolean isNullOrEmpty(Map<?, ?> map) {
return map == null || map.isEmpty();
}
public static void abort() throws Abort {
throw new Abort();
}
public static void throwWhenInterrupted() throws InterruptedException {
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
}
}