12 — Utilities

Message Formatting

rulii includes a message formatting system that supports both positional placeholders ({0}, {1}) and named placeholders (${name}). This is used internally for validation error messages and is available for your own use.

Creating a MessageFormatter

MessageFormatter formatter = MessageFormatter.builder().build();

Simple Messages (No Placeholders)

String result = formatter.format(Locale.getDefault(), "Hello world");
// "Hello world"

Positional Placeholders

Use {0}, {1}, etc. to reference arguments by index:

ParameterInfo[] args = {
    new ParameterInfo(0, "name", "Alice"),
    new ParameterInfo(1, "age", 30)
};

String result = formatter.format(Locale.getDefault(),
    "Name: {0}, Age: {1}", args);
// "Name: Alice, Age: 30"

Named Placeholders

Use ${name} to reference arguments by their parameter name. You can reuse the same placeholder multiple times:

ParameterInfo[] args = {
    new ParameterInfo(0, "name", "Alice"),
    new ParameterInfo(1, "score", 95)
};

String result = formatter.format(Locale.getDefault(),
    "Hello ${name}, your score is ${score}. Congrats ${name}!", args);
// "Hello Alice, your score is 95. Congrats Alice!"

Mixing Both Styles

You can use positional and named placeholders in the same message:

String result = formatter.format(Locale.getDefault(),
    "${name} scored {1} points. Well done ${name}!", args);
// "Alice scored 95 points. Well done Alice!"

Number Formatting

Use Java MessageFormat patterns for number formatting:

ParameterInfo[] args = {
    new ParameterInfo(0, "label", "Total"),
    new ParameterInfo(1, "amount", 123)
};

String result = formatter.format(Locale.getDefault(),
    "{0}: {1,number,integer}", args);
// "Total: 123"

Parsing Templates

You can parse a template string to inspect its placeholders:

String template = "Name: ${name}, Age: ${age}";
FormattedText formatted = FormattedTextParser.parse(template);

boolean hasPlaceholders = formatted.hasPlaceholders(); // true
List<Placeholder> namePlaceholders = formatted.getPlaceholder("name");
// namePlaceholders.size() == 1
// namePlaceholders.get(0).getName() == "name"