All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.rapidpm.frp.StringFunctions Maven / Gradle / Ivy

There is a newer version: 01.00.07-RPM
Show newest version
/**
 * Copyright © 2017 Sven Ruppert ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.rapidpm.frp;

import static java.lang.Character.toChars;
import static java.lang.Integer.parseInt;
import static java.lang.String.valueOf;
import static java.util.regex.Pattern.CASE_INSENSITIVE;
import static java.util.stream.Collectors.joining;
import static org.rapidpm.frp.Transformations.not;
import static org.rapidpm.frp.matcher.Case.match;
import static org.rapidpm.frp.matcher.Case.matchCase;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.rapidpm.frp.functions.QuadFunction;
import org.rapidpm.frp.functions.TriFunction;
import org.rapidpm.frp.matcher.Case;
import org.rapidpm.frp.model.Result;

/**
 * Created by svenruppert on 25.04.17.
 *
 * @author svenruppert
 * @version $Id: $Id
 */
public interface StringFunctions {

  /**
   * 

notStartsWith.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction notStartsWith() { return (s, prefix) -> ! s.startsWith(prefix); } /** *

notStartsWithCaseSensitive.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction notStartsWithCaseSensitive() { return (input, prefix, caseSensitive) -> (caseSensitive) ? not().apply(input.startsWith(prefix)) : not().apply(input.toLowerCase().startsWith(prefix.toLowerCase())); } /** *

notEmpty.

* * @return a {@link java.util.function.Predicate} object. */ static Predicate notEmpty() { return (str) -> not().apply(str.isEmpty()); } /** * Get the character at index. *

* This is not 0 based. The first Element will addressed with a 1 !! *

* For values which don't fall under this range Result.failure will be returned. *

* param value input value * param index location * * @return an Optional String if found else empty */ static BiFunction> at() { return (String value, Integer humanIndex) -> match( matchCase(() -> Result.success(valueOf(value.charAt(humanIndex - 1)))), matchCase(() -> value == null, () -> Result.failure("value should not be null")), matchCase(value::isEmpty, () -> Result.failure("value should not be empty")), matchCase(() -> humanIndex - 1 >= value.length(), () -> Result.failure("index out of bounds")), matchCase(() -> humanIndex - 1 < 0, () -> Result.failure("index out of lower bounds")) ); } /** * Replace consecutive whitespace characters with a single space. *

* param input input String * * @return collapsed String */ static Function collapseWhitespace() { return (input) -> input.trim().replaceAll("\\s\\s+", " "); } /** * Verifies that the needle is contained in the value. The search is case insensitive *

* param value to search * param needle to find * * @return true if found else false. */ static BiFunction contains() { return (value, needle) -> containsCaseSensitive().apply(value, needle, false); } /** * Verifies that the needle is contained in the value. *

* param value to search * param needle to find * param caseSensitive true or false * * @return true if found else false. */ static TriFunction containsCaseSensitive() { return (value, needle, caseSensitive) -> match( matchCase(() -> Result.success(value.toLowerCase().contains(needle.toLowerCase()))), matchCase(() -> caseSensitive, () -> Result.success(value.contains(needle))) ).get(); } /** * Verifies that all needles are contained in value. The search is case insensitive *

* param value input String to search * param needles needles to find * * @return true if all needles are found else false. */ static BiFunction containsAll() { return (value, needles) -> Arrays .stream(needles) .allMatch(needle -> containsCaseSensitive().apply(value, needle, true)); } /** * Verifies that all needles are contained in value *

* param value input String to search * param needles needles to find * param caseSensitive true or false * * @return true if all needles are found else false. */ static TriFunction containsAllCaseSensitive() { return (value, needles, caseSensitive) -> Arrays .stream(needles) .allMatch(needle -> containsCaseSensitive().apply(value, needle, caseSensitive)); } /** *

containsAny.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction containsAny() { return (value, needles) -> containsAnyCaseSensitive().apply(value, needles, false); } /** *

containsAnyCaseSensitive.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction containsAnyCaseSensitive() { return (value, needles, caseSensitive) -> Arrays .stream(needles) .anyMatch(needle -> containsCaseSensitive().apply(value, needle, caseSensitive)); } /** *

countSubStr.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction countSubStr() { return (value, subStr) -> countSubStrCaseSensitive().apply(value, subStr, true, false); } /** *

countSubStrCaseSensitive.

* * @return a {@link org.rapidpm.frp.functions.QuadFunction} object. */ static QuadFunction countSubStrCaseSensitive() { return (value, subStr, caseSensitive, allowOverlapping) -> countSubStrCaseSensitiveOverlapping() .apply( caseSensitive ? value : value.toLowerCase(), caseSensitive ? subStr : subStr.toLowerCase(), allowOverlapping, 0L); } /** *

countSubStrCaseSensitiveOverlapping.

* * @return a {@link org.rapidpm.frp.functions.QuadFunction} object. */ static QuadFunction countSubStrCaseSensitiveOverlapping() { return (value, subStr, allowOverlapping, count) -> { int position = value.indexOf(subStr); if (position == - 1) { return count; } int offset; if (! allowOverlapping) { offset = position + subStr.length(); } else { offset = position + 1; } return countSubStrCaseSensitiveOverlapping().apply(value.substring(offset), subStr, allowOverlapping, ++ count); }; } /** *

endsWith.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction endsWith() { return (value, search) -> endsWithCaseSensitive().apply(value, search, true); } /** * Test if value ends with search. *

* param value input string * param search string to search * param caseSensitive true or false * * @return true or false */ static TriFunction endsWithCaseSensitive() { return (value, search, caseSensitive) -> endsWithCaseSensitiveUpTo() .apply(value, search, value.length(), caseSensitive); } /** *

endsWithCaseSensitiveUpTo.

* * @return a {@link org.rapidpm.frp.functions.QuadFunction} object. */ static QuadFunction endsWithCaseSensitiveUpTo() { return (value, search, position, caseSensitive) -> { int remainingLength = position - search.length(); return (caseSensitive) ? value.indexOf(search, remainingLength) > - 1 : value.toLowerCase().indexOf(search.toLowerCase(), remainingLength) > - 1; }; } /** *

ensureLeft.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction ensureLeft() { return (input, prefix) -> ensureLeftCaseSensitive().apply(input, prefix, true); } /** *

ensureLeftCaseSensitive.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction ensureLeftCaseSensitive() { return (input, prefix, caseSensitive) -> (caseSensitive) ? (input.startsWith(prefix) ? input : (prefix + input)) : (input.toLowerCase().startsWith(prefix.toLowerCase()) ? input : (prefix + input)); } /** *

base64Decode.

* * @return a {@link java.util.function.Function} object. */ static Function base64Decode() { return (input) -> new String(Base64.getDecoder().decode(input.getBytes(Charset.forName("UTF-8")))).intern(); } /** *

base64Encode.

* * @return a {@link java.util.function.Function} object. */ static Function base64Encode() { return (input) -> Base64.getEncoder().encodeToString(input.getBytes(Charset.forName("UTF-8"))); } /** *

appendArray.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction appendArray() { return (input, appends) -> appendStream() .apply(input, Arrays.stream(appends)); } /** *

appendStream.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction, String> appendStream() { return (input, appendStream) -> Stream .concat( Stream.of(input), appendStream) .collect(joining()); } /** *

append.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction append() { return (input, append) -> appendStream() .apply(input, Stream.of(append)); } /** *

appendCollection.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction, String> appendCollection() { return (input, appendCollection) -> appendStream().apply(input, appendCollection.stream()); } /** * Returns a repeated string given a multiplier. *

* param value The input String * param multiplier Number of repeats * * @return The String repeated */ static BiFunction repeat() { return (input, repeat) -> Stream .generate(() -> input) .limit(repeat) .collect(joining()); } /** * Returns a new string of a given length such that the beginning of the string is padded. *

* param value The input String * param pad The pad * param length Length of the String we want * * @return Padded String */ static TriFunction leftPad() { return (value, pad, length) -> (value.length() > length) ? value : append().apply(repeat().apply(pad, length - value.length()), value); } /** *

decode.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction decode() { return (value, digits, radix) -> Arrays .stream(value.split("(?<=\\G.{" + digits + "})")) .map(data -> valueOf(toChars(parseInt(data, radix)))) .collect(joining()); } /** *

encode.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction encode() { return (value, digits, radix) -> value .chars() .mapToObj(ch -> leftPad() .apply(Integer.toString(ch, radix), "0", digits)) .collect(joining()); } /** * Convert binary unicode (16 digits) string to string chars *

* param value The value to decode * * @return The decoded String */ static Function binDecode() { return (value) -> decode().apply(value, 16, 2); } /** * Convert string chars to binary unicode (16 digits) *

* param value The value to encode * * @return String in binary format */ static Function binEncode() { return (value) -> encode().apply(value, 16, 2); } /** * Convert decimal unicode (5 digits) string to string chars *

* param value The value to decode * * @return decoded String */ static Function decDecode() { return (value) -> decode().apply(value, 5, 10); } /** * Convert string chars to decimal unicode (5 digits) *

* param value The value to encode * * @return Encoded value */ static Function decEncode() { return (value) -> encode().apply(value, 5, 10); } /** * Ensures that the value ends with suffix. If it doesn't, it's appended. This operation is case sensitive. *

* param value The input String * param suffix The substr to be ensured to be right * * @return The string which is guarenteed to start with substr */ static BiFunction ensureRight() { return (value, suffix) -> ensureRightCaseSensitive().apply(value, suffix, true); } /** * Ensures that the value ends with suffix. If it doesn't, it's appended. *

* param value The input String * param suffix The substr to be ensured to be right * param caseSensitive Use case (in-)sensitive matching for determining if value already ends with suffix * * @return The string which is guarenteed to start with substr */ static TriFunction ensureRightCaseSensitive() { return (value, suffix, caseSensitive) -> endsWithCaseSensitive().apply(value, suffix, caseSensitive) ? value : append().apply(value, suffix); } /** * Returns the first n chars of String *

* param value The input String * param n Number of chars to return * * @return The first n chars */ static BiFunction first() { return (value, n) -> value.substring(0, n); } /** * Return the first char of String *

* param value The input String * * @return The first char */ static Function head() { return (value) -> first().apply(value, 1); } /** * Formats a string using parameters *

* param value The value to be formatted * param params Parameters to be described in the string * * @return The formatted string */ static BiFunction format() { return (input, params) -> { //TODO refactor to fp final Pattern p = Pattern.compile("\\{(\\w+)\\}"); final Matcher m = p.matcher(input); String result = input; while (m.find()) { int paramNumber = Integer.parseInt(m.group(1)); if (params == null || paramNumber >= params.length) { throw new IllegalArgumentException("params does not have value for " + m.group()); } result = result.replace(m.group(), params[paramNumber]); } return result; }; } /** * Convert hexadecimal unicode (4 digits) string to string chars *

* param value The value to decode * * @return The decoded String */ static Function hexDecode() { return (input) -> decode().apply(input, 4, 16); } /** * Convert string chars to hexadecimal unicode (4 digits) *

* param value The value to encode * * @return String in hexadecimal format. */ static Function hexEncode() { return (input) -> encode().apply(input, 4, 16); } /** * The indexOf() method returns the index within the calling String of the first occurrence of the specified value, starting the search at fromIndex. * Returns -1 if the value is not found. *

* param value The input String * param needle The search String * param offset The offset to start searching from. * param caseSensitive boolean to indicate whether search should be case sensitive * * @return Returns position of first occurrence of needle. */ static QuadFunction indexOfCoseSensitive() { return (value, needle, offset, caseSensitive) -> (caseSensitive) ? value.indexOf(needle, offset) : value.toLowerCase().indexOf(needle.toLowerCase(), offset); } /** * Tests if two Strings are inequal *

* param first The first String * param second The second String * * @return true if first and second are not equal false otherwise */ static BiFunction inEqual() { return (first, second) -> ! Objects.equals(first, second); } /** * Inserts 'substr' into the 'value' at the 'index' provided. *

* param value The input String * param substr The String to insert * param index The index to insert substr * * @return String with substr added */ static TriFunction insert() { return (value, subStr, index) -> (index > value.length()) ? value : appendStream() .apply( value.substring(0, index), Stream.of( subStr, value.substring(index))); } /** * Verifies if String is uppercase *

* param value The input String * * @return true if String is uppercase false otherwise */ static Function isUpperCase() { return (input) -> Objects.equals(input, input.toUpperCase()); } /** * Verifies if String is lower case *

* param value The input String * * @return true if String is lowercase false otherwise */ static Function isLowerCase() { return (input) -> Objects.equals(input, input.toLowerCase()); } /** * Return the last n chars of String *

* param value The input String * param n Number of chars to return * * @return n Last characters */ static BiFunction last() { return (value, n) -> (n > value.length()) ? value : value.substring(value.length() - n); } /** * Checks whether Object is String * * @param value The input String * @return true if Object is a String false otherwise */ public static boolean isString(final Object value) { if (Objects.isNull(value)) { throw new IllegalArgumentException("value can't be null"); } return value instanceof String; } /** * This method returns the index within the calling String object of the last occurrence of the specified value, searching backwards from the offset. * Returns -1 if the value is not found. The search starts from the end and case sensitive. *

* param value The input String * param needle The search String * * @return Return position of the last occurrence of 'needle'. */ static BiFunction lastIndexOf() { return (value, needle) -> lastIndexOfCaseSensitive().apply(value, needle, true); } /** * This method returns the index within the calling String object of the last occurrence of the specified value, searching backwards from the offset. * Returns -1 if the value is not found. The search starts from the end and case sensitive. *

* param value The input String * param needle The search String * param caseSensitive true or false * * @return Return position of the last occurrence of 'needle'. */ static TriFunction lastIndexOfCaseSensitive() { return (value, needle, caseSensitive) -> lastIndexOfCaseSensitiveWithIndexOf().apply(value, needle, value.length(), caseSensitive); } /** * This method returns the index within the calling String object of the last occurrence of the specified value, searching backwards from the offset. * Returns -1 if the value is not found. *

* param value The input String * param needle The search String * param offset The index to start search from * param caseSensitive whether search should be case sensitive * * @return Return position of the last occurrence of 'needle'. */ static QuadFunction lastIndexOfCaseSensitiveWithIndexOf() { return (value, needle, offset, caseSensitive) -> (caseSensitive) ? value.lastIndexOf(needle, offset) : value.toLowerCase().lastIndexOf(needle.toLowerCase(), offset); } /** * Removes all spaces on left *

* param value The input String * * @return String without left border spaces */ static Function leftTrim() { return (value) -> value.replaceAll("^\\s+", ""); } /** * Returns length of String. Delegates to java.lang.String length method. *

* param value The input String * * @return Length of the String */ static Function length() { return String::length; } /** * Return a new String starting with prepends *

* param value The input String * param prepends Strings to prepend * * @return The prepended String */ static BiFunction prependArray() { return (value, array) -> Arrays.stream(array).collect(joining()) + value; } /** * Return a new String starting with prepends *

* param value The input String * param prepends Strings to prepend * * @return The prepended String */ static BiFunction, String> prependStream() { return (value, stream) -> stream.collect(joining()) + value; } /** * Remove empty Strings from string array *

* param strings Array of String to be cleaned * * @return Array of String without empty Strings */ static Function removeEmptyStrings() { return (input) -> Arrays .stream(input) .filter(Objects::nonNull) .map(String::trim) .filter(notEmpty()) .toArray(String[]::new); } /** * Returns a new String with the prefix removed, if present. This is case sensitive. *

* param value The input String * param prefix String to remove on left * * @return The String without prefix */ static BiFunction removeLeft() { return (input, prefix) -> input.startsWith(prefix) ? input.replaceFirst(prefix, "") : input; } /** *

removeFromLeftCaseSensitive.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction removeFromLeftCaseSensitive() { return (input, prefix, caseSenstive) -> (caseSenstive) ? removeLeft().apply(input, prefix) : (notStartsWithCaseSensitive().apply(input, prefix, false)) ? input : input.substring(prefix.length()); } /** *

startsWith.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction startsWith() { return String::startsWith; } /** *

removeNonWord.

* * @return a {@link java.util.function.Function} object. */ static Function removeNonWord() { return (value) -> value.replaceAll("[^\\w]+", ""); } /** *

removeRight.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction removeRight() { return (value, suffix) -> removeRightCaseSensitive().apply(value, suffix, true); } /** *

removeRightCaseSensitive.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction removeRightCaseSensitive() { return (value, suffix, caseSensitive) -> endsWithCaseSensitive().apply(value, suffix, caseSensitive) ? value.substring(0, value.toLowerCase().lastIndexOf(suffix.toLowerCase())) : value; } /** * Remove all spaces and replace for value. *

* param value The input String * * @return String without spaces */ static Function removeSpaces() { return (value) -> value.replaceAll("\\s", ""); } /** * Replace all occurrences of 'search' value to 'newvalue'. Uses String replace method. *

* param value The input * param search The String to search * param newValue The String to replace * param caseSensitive whether search should be case sensitive or not * * @return String replaced with 'newvalue'. */ static QuadFunction replace() { return (value, search, newValue, caseSensitive) -> (caseSensitive) ? value.replaceAll(search, newValue) : Pattern .compile(search, CASE_INSENSITIVE) .matcher(value) .replaceAll(Matcher.quoteReplacement(newValue)); } /** * Reverse the input String *

* param value The input String * * @return Reversed String */ static Function reverse() { return (value) -> new StringBuilder(value).reverse().toString(); } /** * Returns a new string of a given length such that the ending of the string is padded. *

* param value The input String * param length Max length of String. * param pad Character to repeat * * @return Right padded String */ static TriFunction rightPad() { return (value, pad, length) -> (value.length() > length) ? value : append().apply(value, repeat().apply(pad, length - value.length())); } /** *

rightTrim.

* * @return a {@link java.util.function.Function} object. */ static Function rightTrim() { return (value) -> value.replaceAll("\\s+$", ""); } /** *

split.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction split() { return String::split; } /** *

splitStream.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction> splitStream() { return (input, regex) -> Arrays.stream(input.split(regex)); } /** *

join.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction join() { return (strings, sperator) -> Arrays.stream(strings).collect(joining(sperator)); } /** *

wordStream.

* * @return a {@link java.util.function.Function} object. */ static Function> wordStream() { return (input) -> Arrays.stream(input.split("\\W+")); } /** *

truncate.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction truncate() { return (value, length, filler) -> Case .match( Case.matchCase( () -> Result.success( append().apply(value.substring(0, length - filler.length()), filler))), Case.matchCase(() -> length == 0, () -> Result.success("")), Case.matchCase(() -> length >= value.length(), () -> Result.success(value)) ).get(); } /** *

chars.

* * @return a {@link java.util.function.Function} object. */ static Function chars() { return (input) -> input.split(""); } /** *

charsStream.

* * @return a {@link java.util.function.Function} object. */ static Function> charsStream() { return (input) -> Arrays.stream(input.split("")); } /** *

shuffle.

* * @return a {@link java.util.function.Function} object. */ static Function shuffle() { return (input) -> { final String[] chars = chars().apply(input); Random random = new Random(); for (int i = 0; i < chars.length; i++) { int r = random.nextInt(chars.length); String tmp = chars[i]; chars[i] = chars[r]; chars[r] = tmp; } return Arrays.stream(chars).collect(joining()); }; } /** *

slice.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction slice() { return String::substring; } /** *

surround.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction surround() { return (value, prefix, suffix) -> Case .match( Case.matchCase(() -> Result.success(prefix + value + suffix)), Case.matchCase(() -> prefix == null && suffix == null, () -> Result.success(value)), Case.matchCase(() -> prefix != null && suffix == null, () -> Result.success(prefix + value + prefix)), Case.matchCase(() -> prefix == null && suffix != null, () -> Result.success(suffix + value + suffix)) ).get(); } /** *

toCamelCase.

* * @return a {@link java.util.function.Function} object. */ static Function toCamelCase() { return (value) -> toStudlyCase() .apply(value) .substring(0, 1) .toLowerCase() + toStudlyCase() .apply(value) .substring(1); } /** *

toStudlyCase.

* * @return a {@link java.util.function.Function} object. */ static Function toStudlyCase() { return (value) -> splitStream() .apply(collapseWhitespace().apply(value.trim()), "\\s*(_|-|\\s)\\s*") .filter(w -> ! w.trim().isEmpty()) .map(w -> head().apply(w).toUpperCase() + tail().apply(w)) .collect(joining()); } /** *

tail.

* * @return a {@link java.util.function.Function} object. */ static Function tail() { return (value) -> last().apply(value, value.length() - 1); } /** *

toDecamelize.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction toDecamelize() { return (value, chr) -> splitStream() .apply(toCamelCase().apply(value), "(?=\\p{Upper})") .map(String::toLowerCase) .collect(joining(chr)); } /** *

toKebabCase.

* * @return a {@link java.util.function.Function} object. */ static Function toKebabCase() { return (value) -> toDecamelize().apply(value, "-"); } /** *

toSnakeCase.

* * @return a {@link java.util.function.Function} object. */ static Function toSnakeCase() { return (value) -> toDecamelize().apply(value, "_"); } //TODO refactoring - remove optinal /** *

capitalize.

* * @return a {@link java.util.function.Function} object. */ static Function capitalize() { return (input) -> (input.length() == 0) ? "" : Optional .ofNullable(head().apply(input)) .map(String::toUpperCase) .map(h -> Optional .ofNullable(tail().apply(input)) .map(t -> h + t.toLowerCase()) .orElse(h)) .get(); } //TODO refactoring - remove optinal /** *

lowerFirst.

* * @return a {@link java.util.function.Function} object. */ static Function lowerFirst() { return (input) -> (input.length() == 0) ? "" : Optional.ofNullable(head().apply(input)) .map(String::toLowerCase) .map(h -> Optional.ofNullable(tail().apply(input)).map(t -> h + t).orElse(h)) .get(); } /** *

isEnclosedBetween.

* * @return a {@link java.util.function.BiFunction} object. */ static BiFunction isEnclosedBetween() { return (input, encloser) -> input.startsWith(encloser) && input.startsWith(encloser); } /** *

isEnclosedBetweenBoth.

* * @return a {@link org.rapidpm.frp.functions.TriFunction} object. */ static TriFunction isEnclosedBetweenBoth() { return (input, left, right) -> input.startsWith(left) && input.startsWith(right); } /** *

upperFirst.

* * @return a {@link java.util.function.Function} object. */ static Function upperFirst() { return (input) -> Optional .ofNullable(head().apply(input)) .map(String::toUpperCase) .map(h -> Optional .ofNullable(tail().apply(input)) .map(t -> h + t) .orElse(h)) .get(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy