Variant.java
package io.github.jonloucks.variants.api;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import static io.github.jonloucks.variants.api.Checks.keyCheck;
import static io.github.jonloucks.variants.api.Checks.keysCheck;
import static java.util.Collections.singletonList;
/**
* Responsibility: Provide information on how to retrieve a configuration value.
*
* @param <T> the type of configuration value
*/
public interface Variant<T> {
/**
* The primary use case of getting a property value by key
* @return the ordered list of keys used to search for values.
*/
default List<String> getKeys() {
return Collections.emptyList();
}
/**
* Note: The name is not used to look up values!
* Note: if name is not set the first key might be used
* @return The user facing name of this Variant
*/
default Optional<String> getName() {
return Optional.empty();
}
/**
* @return the optional description
*/
default Optional<String> getDescription() {
return Optional.empty();
}
/**
* @return the optional fallback value. aka default value
*/
default Optional<T> getFallback() {
return Optional.empty();
}
/**
* Links can be helpful when a Variant which does not
* have an explicit value can default the value of another Variant.
* @return The optional link to another Variant
*/
default Optional<Variant<T>> getLink() {
return Optional.empty();
}
/**
* Parses the
* Note: Required if keys are used to retrieve a value.
* Note: implementations of this function should return empty on null values.
* @param rawText the text to be parsed
* @return the optional Variance
*/
default Optional<T> of(CharSequence rawText) {
return Optional.empty();
}
/**
* Responsibility: Configuration for creating a new Variant.
*
* @param <T> type Variant value type
*/
interface Config<T> {
/**
* The primary use case of getting a property value by key
* @return the ordered list of keys used to search for values.
*/
default List<String> getKeys() {
return Collections.emptyList();
}
/**
* Note: The name is not used to look up values!
* @return The user facing name of this Variant
*/
default Optional<String> getName() {
return Optional.empty();
}
/**
* @return the optional description
*/
default Optional<String> getDescription() {
return Optional.empty();
}
/**
* @return the optional fallback value. aka default value
*/
default Optional<T> getFallback() {
return Optional.empty();
}
/**
* Links can be helpful when a Variant which does not
* have an explicit value can default the value of another Variant.
* @return The optional link to another Variant
*/
default Optional<Variant<T>> getLink() {
return Optional.empty();
}
/**
* @return The parser used to convert raw text into a Variant value
*/
default Optional<Function<CharSequence, T>> getParser() {
return Optional.empty();
}
/**
* Responsibility: Builder a configuration used to create a new Variant
*
* @param <T> type Variant value type
*/
interface Builder<T> extends Config<T> {
/**
* Add a new key
*
* @param key the key to add
* @return this Builder
*/
default Builder<T> key(String key) {
return keys(singletonList(keyCheck(key)));
}
/**
* Add a variable number of keys
*
* @param keys the keys to add
* @return this Builder
*/
default Builder<T> keys(String... keys) {
return keys(Arrays.asList(keysCheck(keys)));
}
/**
* Add a collection of keys
*
* @param keys the keys to add
* @return this Builder
*/
Builder<T> keys(Collection<String> keys);
/**
* Assign the name
*
* @param name the new name
* @return this Builder
*/
Builder<T> name(String name);
/**
* Assign the parser to convert text into Variant values
* A parser can return null for any reason, it is processed as unassigned
*
* @param parser the parser
* @return this Builder
*/
Builder<T> parser(Function<CharSequence, T> parser);
/**
* Assign the description
*
* @param description the description
* @return this Builder
*/
Builder<T> description(String description);
/**
* Assign the fallback value supplier
*
* @param fallback the fallback value supplier
* @return this Builder
*/
Builder<T> fallback(Supplier<T> fallback);
/**
* Assign a link
* @param link the link
* @return this Builder
*/
Builder<T> link(Variant<T> link);
}
}
}