Skip to content

Validation

fzzyhmstrs edited this page Apr 21, 2024 · 10 revisions

One of Fzzy Configs most powerful features is the validation system that is applied to every setting either implicitly or explicitly by the creator.

Every setting is tightly controlled and fail-soft; no need to worry about catastrophic failure of a mod system if the config changes and the old file isn't valid. No need to worry if a user modifies one of the .toml directly.

Every read, write, and update is checked for errors and problems are either automatically corrected or shunted to the default value.

Validation Options

Below is a (potentially non-exhaustive) list of types that Fzzy Config has validation tools for.

  • Integer
  • Long
  • Short
  • Byte
  • Double
  • Float
  • Boolean
  • Lists
  • Sets
  • Maps
  • Enums
  • Mathematical Expression
  • Color
  • Identifier
  • TagKey
  • Ingredient
  • Arbitrary Objects

Validation Concepts

What is it?

"Validation" is a bit of a misnomer, as the toolset does much more than that. It's a label of convenience stemming from the base class ValidatedField. Validation tools provide a set of tools to handle settings in various ways. To borrow from the KDoc for Entry, validation tools do the following:

  • serialize contents
  • deserialize input
  • validate updates
  • correct errors
  • provide widgets
  • apply inputs
  • supply outputs
  • create instances

Providing Validation

Every setting that appears in a Config GUI is backed in some way by validation. Even when you don't explicitly provide it, Fzzy Config will wrap supported types with basic validation in the background.

  • If you try to add a setting of an unsupported type, you will need to create custom validation for it, or it will not appear in config GUIs

For more specific control of your settings, in the vein of Minecraft GameOption, define the validation for your setting. This grants you the ability to:

  • Provide input restrictions
  • Suggest inputs to users
  • In some places define the widget used in-game

Numbers

All primitive number types have validation tools. Validation:

  • Controls the number type: bytes stay bytes etc.
  • Define a minimum allowable value
  • Define a maximum value

ValidatedNumber

Number validation can be defined by using one of the six subclasses of ValidatedNumber. By default the allowable min and max will be the entire range of the type (Integer.MIN_VALUE to Integer.MAX_VALUE, for example)

//kotlin
var myValidatedFloat = ValidatedFloat(0.5f,1f,0f) // default value, max value, min value
//java
public ValidatedFloat myValidatedFloat = new ValidatedFloat(0.5f,1f,0f); // default value, max value, min value

Annotations

Validated Numbers each have their own partnered Annotation you can use to annotate an otherwise plain field with.

// kotlin
@ValidatedFloat.Restrict(0f,1f)
var myValidatedFloat = 0.5f
// java
@ValidatedFloat.Restrict(min = 0f, max = 1f)
public float myValidatedFloat = 0.5f

Shorthands

Fzzy Config has shorthand contructors for validated numbers. These are generally used to provide Validators for other validation constructors, like Lists or Maps, where you need a ValidatedNumber but may not have any actual need for restrictions.

// kotlin
var myValidatedFloat = ValidatedFloat()
//java
public ValidatedFloat myValidatedFloat = new ValidatedFloat();

Booleans

Booleans are very simple things. In general, you never need to define validation for booleans except when needed for use in other validation.

// kotlin
var myValidatedBoolean = ValidatedBoolean()
//java
public ValidatedBoolean myValidatedBoolean = new ValidatedBoolean();

Collections

Fzzy Config has validation tools for lists, maps, and sets. Each of these constructs has builders and other intricacies that are best digested thoroughly by visiting the documentation:

Validated Collections

NOTE: Validated collections implement their respective collection type (list, set, map), so can be used directly as such instead of having to .get() the wrapped map value.

Validation Conversion

Any ValidatedField can be converted into a list implementation with it as backing validation using the toList() method

//kotlin
//wraps the vararg valued provided with a blank validated field (identifiers in this case). validation with actual bounds and logic can of course be used too
val listFromField = ValidatedIdentifier().toList(Identifier("stick"), Identifier("blaze_rod"))
//java
//wraps the vararg valued provided with a blank validated field (identifiers in this case). validation with actual bounds and logic can of course be used too
public ValidatedList<Identifier> listFromField = new ValidatedIdentifier().toList(new Identifier("stick"), new Identifier("blaze_rod"));

Static Initializers

ValidatedList and Set have a series of static methods that can be used to initialize a variety of collections of given common types, much in the same vein as the java List.of() or kotlin listOf().

// kotlin
var validatedIntList = ValidatedList.ofInt(1,2,5,10)
var validatedIntSet = ValidatedSet.ofInt(1,2,5,10)
// java
public ValidatedList<Integer> validatedIntList = ValidatedList.ofInt(1,2,5,10);
public ValidatedSet<Integer> validatedIntSet = ValidatedSet.ofInt(1,2,5,10);

Enums

Any enum included in a Config is automatically validated, but much like booleans making ValidatedEnums may be useful for constructing other valdiation types.

// kotlin
enum class MyEnum{
    A,
    B,
    C
}

var validatedEnum = ValidatedEnum(MyEnum.A)
var validatedEnumExtension = MyEnum.A.validated() // kotlin extension function for validating an enum automatically
// java
public enum MyEnum{
    A,
    B,
    C
}

public ValidatedEnum<MyEnum> validatedEnum = new ValidatedEnum(MyEnum.A);

Translation

Enums can implement a special interface EnumTranslatable. See Translation for details.

Math Expression

Fzzy Config has a built-in math engine called Expression. See the Expressions article for more details.

Color

Fzzy Config has a built-in Color system with full validation support and conversion to and from RGB, RGB integers, hex strings, and more. See the Colors article for more details.

Identifier

ValidatedIdentifier is one of the more powerful validation tools at the Fzzy Config modders disposal. ValidatedIdentifier can provide:

  • Suggestions for allowable identifiers
  • Restrictions based on tags, registries, or pre-defined lists
  • ValidatedIdentifier implements most methods that Identifier itself does.

For more details, check out the related documentation:

TagKey

FzzyConfig can automatically validate TagKeys from any registry. Validated Tags also provide suggestions to the user.

// kotlin
// Validated tags accept a predicate that can be used to filter a tag further.
var validatedTag = ValidatedTagKey(ItemTags.AXES, {id -> id.namespace == "minecraft})
var shortHandTag = ItemTags.AXES.validated() // kotlin extension function for quick validation
// java
// Validated tags accept a predicate that can be used to filter a tag further.
public ValidatedTagKey<Item> validatedTag = ValidatedTagKey(ItemTags.AXES, {id -> id != Identifier("netherite_axe")})

Ingredient

Minecraft ingredients can be validated, with restrictions placed on the three ways you can construct Ingredients (single item, item list, item tag)

Creation

ValidatedIngredients are constructed from one of three constructors based on the type of ingredient desired as default

// kotlin
// A validated Ingredient for a single item
val validatedIngredientItem = ValidatedIngredient(Identifier("oak_log"))

// A validated ingredient accepting a set of items
val validatedIngredientList = ValidatedIngredient(setOf(Identifier("oak_log"),Identifier("dark_oak_log")))

// A validated ingredient utilizing a tag
val validatedIngredientTag = ValidatedIngredient(ItemTags.LOGS_THAT_BURN)

//get the ingredient from the holder for use in Materials etc
val validatedIngredientIngredient: Ingredient = validatedIngredientItem.toIngredient()
//java
// A validated Ingredient for a single item
public ValidatedIngredient validatedIngredientItem = new ValidatedIngredient(new Identifier("oak_log"));

// A validated ingredient accepting a set of items
public ValidatedIngredient validatedIngredientList = new ValidatedIngredient(Set.of(new Identifier("oak_log"),new Identifier("dark_oak_log")));

// A validated ingredient utilizing a tag
public ValidatedIngredient validatedIngredientTag = new ValidatedIngredient(ItemTags.LOGS_THAT_BURN);

//get the ingredient from the holder for use in Materials etc
public Ingredient validatedIngredientIngredient = validatedIngredientItem.toIngredient()

Usage

ValidatedIngredient is not an ingredient itself, and does not hold ingredients. It lazily creates ingredients only when needed. This prevents an ingredient from being created before the source for the ingredient is ready (before a tag is populated, for example). As seen in the code examples above, call toIngredient() to have the validation supply an ingredient.

Object

Arbitrary POJO/POKO can be validated. Fzzy Config will automatically wrap any object that implements Walkable, or you can construct validation manually with ValidatedAny. The validation constructs a "mini-config" around the object; any validation or validatable fields included within the object will be validated just like a proper config.

See examples of ValidatedAny at Laying out Configs

Clone this wiki locally