package com.googlecode.totallylazy;
import com.googlecode.totallylazy.annotations.multimethod;
import com.googlecode.totallylazy.annotations.tailrec;
import com.googlecode.totallylazy.functions.*;
import com.googlecode.totallylazy.comparators.Maximum;
import com.googlecode.totallylazy.comparators.Minimum;
import com.googlecode.totallylazy.predicates.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import static com.googlecode.totallylazy.Closeables.using;
import static com.googlecode.totallylazy.LazyException.lazyException;
import static com.googlecode.totallylazy.predicates.Predicates.notNullValue;
import static com.googlecode.totallylazy.predicates.Predicates.or;
import static com.googlecode.totallylazy.Sequences.characters;
import static com.googlecode.totallylazy.Sequences.repeat;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.totallylazy.Streams.inputStreamReader;
import static com.googlecode.totallylazy.Strings.toString;
import static com.googlecode.totallylazy.io.Uri.uri;
public class Strings {
public static final String EMPTY = "";
public static final Charset UTF8 = Charset.forName("UTF-8");
public static final Monoid<String> join = ConcatString.instance;
public static Function1<String, Boolean> asBoolean() {
return Boolean::parseBoolean;
}
public static Sequence<String> lines(File file) {
return Streams.lines(file).memorise();
}
public static Sequence<String> lines(InputStream stream) {
return Streams.lines(stream).memorise();
}
public static Sequence<String> lines(Reader reader) {
return Streams.lines(reader).memorise();
}
public static Sequence<String> lines(String lines) {
return Streams.lines(lines).memorise();
}
public static Function0<String> readLine(final BufferedReader reader) { return Streams.readLine(reader); }
public static Function1<String, String> toLowerCase() {
return String::toLowerCase;
}
public static Function1<String, String> replace(final char oldChar, final char newChar) {
return value -> value.replace(oldChar, newChar);
}
public static Function1<String, String> replace(final CharSequence target, final CharSequence replacement) {
return value -> value.replace(target, replacement);
}
public static Function1<String, String> replaceAll(final String regex, final String replacement) {
return value -> value.replaceAll(regex, replacement);
}
public static Function1<String, String> replaceFirst(final String regex, final String replacement) {
return value -> value.replaceFirst(regex, replacement);
}
public static Function1<String, String> toUpperCase() {
return String::toUpperCase;
}
public static LogicalPredicate<String> startsWith(final String value) {
return new StartsWithPredicate(value);
}
public static Function1<String, Predicate<String>> startsWith() {
return Strings::startsWith;
}
public static LogicalPredicate<String> startsWith(String first, String... rest) {
return or(sequence(rest).cons(first).map(startsWith()));
}
public static LogicalPredicate<String> endsWith(final String value) {
return new EndsWithPredicate(value);
}
public static Function1<String, Predicate<String>> endsWith() {
return Strings::endsWith;
}
public static LogicalPredicate<String> endsWith(String first, String... rest) {
return or(sequence(rest).cons(first).map(endsWith()));
}
public static LogicalPredicate<String> contains(final String value) {
return new ContainsPredicate(value);
}
public static Function1<String, Predicate<String>> equalIgnoringCase() {
return Strings::equalIgnoringCase;
}
public static LogicalPredicate<String> equalIgnoringCase(final String expected) {
return new LogicalPredicate<String>() {
public boolean matches(String actual) {
return expected.equalsIgnoreCase(actual);
}
};
}
public static LogicalPredicate<String> empty = new LogicalPredicate<String>() {
public boolean matches(String value) {
return isEmpty(value);
}
};
public static LogicalPredicate<String> empty() {
return empty;
}
public static LogicalPredicate<String> blank = new LogicalPredicate<String>() {
public boolean matches(String value) {
return isBlank(value);
}
};
public static LogicalPredicate<String> blank() {
return blank;
}
public static boolean isEmpty(String value) {
return value == null || value.equals(EMPTY);
}
public static boolean isBlank(String value) {
return isEmpty(value) || isEmpty(value.trim());
}
public static LogicalPredicate<Character> unicodeControlOrUndefinedCharacter() {
return new LogicalPredicate<Character>() {
public boolean matches(Character character) {
return character > 0x7F;
}
};
}
public static String capitalise(String value) {
if (isEmpty(value)) return value;
return String.valueOf(Character.toTitleCase(value.charAt(0))) + value.substring(1);
}
public static String asString(Object value) {
return value == null ? "" : value.toString();
}
private static multi multi;
public static String string(Object value) {
if(multi == null) multi = new multi(){};
return multi.<String>methodOption(value).getOrElse(String.valueOf(value));
}
@multimethod
public static String string(Void value) {
return "";
}
@multimethod
public static String string(byte[] value) {
return toString(value);
}
@multimethod
public static String string(File value) {
return toString(value);
}
@multimethod
public static String string(InputStream value) {
return toString(value);
}
@multimethod
public static String string(Reader value) {
return toString(value);
}
public static String toString(byte[] bytes) {
return new String(bytes, UTF8);
}
public static String toString(File file) {
try {
return toString(new FileInputStream(file));
} catch (FileNotFoundException e) {
throw lazyException(e);
}
}
public static String toString(final InputStream stream) {
if (stream == null) return EMPTY;
return using(stream, inputStream -> toString(inputStreamReader(inputStream)));
}
public static String toString(Reader reader) {
return using(reader, reader1 -> {
StringBuilder builder = new StringBuilder();
char[] buffer = new char[512];
int read = reader1.read(buffer);
while (read > 0) {
builder.append(buffer, 0, read);
read = reader1.read(buffer);
}
return builder.toString();
});
}
public static Function1<Object, String> format(final String format) {
return value -> String.format(format, value);
}
public static Function1<CharSequence, Sequence<Character>> toCharacters() {
return Sequences::characters;
}
public static Function1<String, String> reverse() {
return Strings::reverse;
}
public static Function1<String, Sequence<String>> split(final String regex) {
if (regex == null) throw new IllegalArgumentException("regex cannot be null");
return s -> sequence(s.split(regex));
}
public static Function1<String, String> substring(final int beginIndex, final int endIndex) {
return value -> substring(value, beginIndex, endIndex);
}
public static String reverse(String original) {
return new StringBuilder(original).reverse().toString();
}
@tailrec
public static String substring(String original, int beginIndex, int endIndex) {
int length = original.length();
int beginIndexPositive = toPositive(length, beginIndex);
int endIndexPositive = toPositive(length, endIndex);
if (beginIndexPositive > endIndexPositive) {
return substring(reverse(original), length - beginIndexPositive, length - endIndexPositive);
}
return original.substring(beginIndexPositive, endIndexPositive);
}
private static int toPositive(int stringLength, int index) {
if (index < 0) {
return stringLength + index;
}
return index;
}
public static Function1<String, Character> characterAt(final int index) {
return s -> s.charAt(index);
}
public static Function1<String, String> trim() {
return String::trim;
}
public static LogicalPredicate<String> palindrome = new LogicalPredicate<String>() {
@Override
public boolean matches(String other) {
return Strings.isPalindrome(other);
}
};
public static LogicalPredicate<String> isPalindrome() {
return palindrome;
}
public static boolean isPalindrome(String other) {
return other.equals(reverse(other));
}
public static byte[] bytes(String value) {
return value.getBytes(UTF8);
}
public static Maximum.Function<String> maximum = Maximum.constructors.maximum((String) null);
public static Minimum.Function<String> minimum = Minimum.constructors.minimum((String) null);
public static class functions {
public static Curried3<String, String, String, String> replaceAll =
(regex, replacemenent, source) -> Strings.replaceAll(regex, replacemenent).apply(source);
}
}