Skip to content

Commit

Permalink
Merge pull request #938 from tahmid-23/feature/formatter-join
Browse files Browse the repository at this point in the history
feat(mini-message): add Formatter#joining
  • Loading branch information
zml2008 authored Dec 10, 2024
2 parents 97b1abe + 73c9e85 commit ede96b3
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
import java.text.NumberFormat;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Arrays;
import java.util.Locale;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.TagPattern;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -139,4 +143,63 @@ public static TagResolver booleanChoice(@TagPattern final @NotNull String key, f
return Tag.inserting(context.deserialize(value ? trueCase : falseCase));
});
}

/**
* Creates a replacement that inserts a list of components. These components are joined together by {@link Component#join(JoinConfiguration.Builder, ComponentLike...)}.
*
* <p>This tag has three optional arguments; a separator, a last separator, and a last separator if serial.
* Each argument must be provided in order, with all preceding arguments present.
* The exact use of these three separators is documented in {@link JoinConfiguration}.</p>
*
* <p>This replacement is auto-closing, so its style will not influence the style of following components.</p>
*
* @param key the key
* @param components the components to join
* @return the placeholder
* @see JoinConfiguration
* @since 4.18.0
*/
public static TagResolver joining(@TagPattern final @NotNull String key, final @NotNull Iterable<? extends ComponentLike> components) {
return TagResolver.resolver(key, (argumentQueue, context) -> {
if (!argumentQueue.hasNext()) {
return Tag.inserting(Component.join(JoinConfiguration.noSeparators(), components));
}

final String separator = argumentQueue.pop().value();
final JoinConfiguration.Builder configBuilder = JoinConfiguration.builder().separator(context.deserialize(separator));

if (argumentQueue.hasNext()) {
final String lastSeparator = argumentQueue.pop().value();
configBuilder.lastSeparator(context.deserialize(lastSeparator));
}

if (argumentQueue.hasNext()) {
final String lastSeparatorIfSerial = argumentQueue.pop().value();
configBuilder.lastSeparatorIfSerial(context.deserialize(lastSeparatorIfSerial));
}

final JoinConfiguration config = configBuilder.build();
return Tag.inserting(Component.join(config, components));
});
}

/**
* Creates a replacement that inserts a list of components. These components are joined together by {@link Component#join(JoinConfiguration.Builder, ComponentLike...)}.
*
* <p>This tag has three optional arguments; a separator, a last separator, and a last separator if serial.
* Each argument must be provided in order, with all preceding arguments present.
* The exact use of these three separators is documented in {@link JoinConfiguration}.</p>
*
* <p>This replacement is auto-closing, so its style will not influence the style of following components.</p>
*
* @param key the key
* @param components the components to join
* @return the placeholder
* @see JoinConfiguration
* @since 4.18.0
*/
public static TagResolver joining(@TagPattern final @NotNull String key, final @NotNull ComponentLike@NotNull... components) {
return joining(key, Arrays.asList(components));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@

import java.time.LocalDateTime;
import java.time.Month;
import java.util.Arrays;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.AbstractTest;
import org.junit.jupiter.api.Test;
Expand All @@ -34,6 +36,7 @@
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.booleanChoice;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.choice;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.date;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.joining;
import static net.kyori.adventure.text.minimessage.tag.resolver.Formatter.number;

public class FormatterTest extends AbstractTest {
Expand Down Expand Up @@ -125,4 +128,37 @@ void testBooleanChoice() {
final Component expected = text("bah");
this.assertParsedEquals(expected, input, booleanChoice("first", true), booleanChoice("second", true), booleanChoice("third", true));
}

@Test
void testJoinSeparator() {
final String input = "<list:, >";
final Iterable<? extends Component> components = Arrays.asList(text("one"), text("two"), text("three"));
final Component expected = Component.join(JoinConfiguration.separator(text(", ")), components);
this.assertParsedEquals(expected, input, joining("list", components));
}

@Test
void testJoinSeparatorWithLastSeparator() {
final String input = "<list:, : and >";
final Iterable<? extends Component> components = Arrays.asList(text("one"), text("two"), text("three"));
final Component expected = Component.join(JoinConfiguration.separators(text(", "), text(" and ")), components);
this.assertParsedEquals(expected, input, joining("list", components));
}

@Test
void testJoinSeparatorWithLastSeparatorIfSerialAndManyComponents() {
final String input = "<list:, : and :, and >";
final Iterable<? extends Component> components = Arrays.asList(text("one"), text("two"), text("three"));
final Component expected = Component.join(JoinConfiguration.builder().separator(text(", ")).lastSeparator(text(" and ")).lastSeparatorIfSerial(text(", and ")), components);
this.assertParsedEquals(expected, input, joining("list", components));
}

@Test
void testJoinSeparatorWithLastSeparatorIfSerialAndTwoComponents() {
final String input = "<list:, : and :, and >";
final Iterable<? extends Component> components = Arrays.asList(text("one"), text("two"));
final Component expected = Component.join(JoinConfiguration.builder().separator(text(", ")).lastSeparator(text(" and ")).lastSeparatorIfSerial(text(", and ")), components);
this.assertParsedEquals(expected, input, joining("list", components));
}

}

0 comments on commit ede96b3

Please sign in to comment.