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"