Exit Full View

Feather2 / feather2-runtime / src / main / java / uk / co / nickthecoder / feather / runtime / FeatherExtensions.java

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();
        }
    }

}