Skip to content

Commit

Permalink
Merge pull request #332 from KyoriPowered/feature/replacement-continu…
Browse files Browse the repository at this point in the history
…er-extra
  • Loading branch information
zml2008 authored Apr 13, 2021
2 parents d92fcb2 + 35c9ffe commit a963b70
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,26 @@ default Builder matchLiteral(final String literal) {
/**
* Set the function to determine how an individual match should be processed.
*
* @param condition a function of {@code (index, replaced)} used to determine if matches should be replaced, where "replaced" is the number of successful replacements.
* @param condition a function of {@code (matchCount, replaced)} used to determine if matches should be replaced, where "matchCount" is the number of matches
* that have been found, including the current one, and "replaced" is the number of successful replacements.
* @return this builder
* @since 4.2.0
*/
@Contract("_ -> this")
@NonNull Builder condition(final @NonNull IntFunction2<PatternReplacementResult> condition);
default @NonNull Builder condition(final @NonNull IntFunction2<PatternReplacementResult> condition) {
return this.condition((result, matchCount, replaced) -> condition.apply(matchCount, replaced));
}

/**
* Set the function to determine how an individual match should be processed.
*
* @param condition a function that determines whether a replacement should occur
* @return this builder
* @see Condition
* @since 4.8.0
*/
@Contract("_ -> this")
@NonNull Builder condition(final @NonNull Condition condition);

/*
* -------------------------
Expand Down Expand Up @@ -207,4 +221,23 @@ default Builder matchLiteral(final String literal) {
@Contract("_ -> this")
@NonNull Builder replacement(final @NonNull BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement);
}

/**
* A function determining whether a certain match should be replaced.
*
* @since 4.8.0
*/
@FunctionalInterface
interface Condition {
/**
* Determine how a single match should be handled.
*
* @param result the current match result
* @param matchCount the number of matches encountered, including this one and matches that were not replaced
* @param replaced the number of matches that have already been replaced
* @return whether a certain match should
* @since 4.8.0
*/
@NonNull PatternReplacementResult shouldReplace(final @NonNull MatchResult result, final int matchCount, final int replaced);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import net.kyori.adventure.util.IntFunction2;
import net.kyori.examination.ExaminableProperty;
import net.kyori.examination.string.StringExaminer;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
Expand All @@ -39,7 +38,7 @@
final class TextReplacementConfigImpl implements TextReplacementConfig {
private final Pattern matchPattern;
private final BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement;
private final IntFunction2<PatternReplacementResult> continuer;
private final Condition continuer;

TextReplacementConfigImpl(final Builder builder) {
this.matchPattern = builder.matchPattern;
Expand Down Expand Up @@ -78,7 +77,7 @@ public String toString() {
static final class Builder implements TextReplacementConfig.Builder {
@MonotonicNonNull Pattern matchPattern;
@MonotonicNonNull BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement;
IntFunction2<PatternReplacementResult> continuer = (index, replacement) -> PatternReplacementResult.REPLACE;
TextReplacementConfig.Condition continuer = (matchResult, index, replacement) -> PatternReplacementResult.REPLACE;

Builder() {
}
Expand All @@ -96,7 +95,7 @@ static final class Builder implements TextReplacementConfig.Builder {
}

@Override
public @NonNull Builder condition(final @NonNull IntFunction2<PatternReplacementResult> condition) {
public @NonNull Builder condition(final TextReplacementConfig.@NonNull Condition condition) {
this.continuer = requireNonNull(condition, "continuation");
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import java.util.regex.Pattern;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.renderer.ComponentRenderer;
import net.kyori.adventure.util.IntFunction2;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

Expand Down Expand Up @@ -60,7 +59,7 @@ private TextReplacementRenderer() {
final Matcher matcher = state.pattern.matcher(content);
int replacedUntil = 0; // last index handled
while(matcher.find()) {
final PatternReplacementResult result = state.continuer.apply(++state.matchCount, state.replaceCount);
final PatternReplacementResult result = state.continuer.shouldReplace(matcher, ++state.matchCount, state.replaceCount);
if(result == PatternReplacementResult.CONTINUE) {
// ignore this replacement
continue;
Expand Down Expand Up @@ -189,13 +188,13 @@ private TextReplacementRenderer() {
static final class State {
final Pattern pattern;
final BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement;
final IntFunction2<PatternReplacementResult> continuer;
final TextReplacementConfig.Condition continuer;
boolean running = true;
int matchCount = 0;
int replaceCount = 0;
boolean firstMatch = true;

State(final @NonNull Pattern pattern, final @NonNull BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement, final @NonNull IntFunction2<PatternReplacementResult> continuer) {
State(final @NonNull Pattern pattern, final @NonNull BiFunction<MatchResult, TextComponent.Builder, @Nullable ComponentLike> replacement, final TextReplacementConfig.@NonNull Condition continuer) {
this.pattern = pattern;
this.replacement = replacement;
this.continuer = continuer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,13 +218,32 @@ void testReplaceAtStart() {
void testReplaceAtStartReturnsChild() {
final Component base = Component.text("value");

final Component replaced = base.replaceText(c -> c.match("value").replacement((matchResult, builder) -> {
return Component.text("").append(Component.text("1337"));
}).build());
final Component replaced = base.replaceText(c -> c.match("value")
.replacement((matchResult, builder) -> Component.text("").append(Component.text("1337"))));

final Component expected = Component.text()
.append(Component.text("1337"))
.build();
assertEquals(expected, replaced);
}

@Test
void testReplaceWithMatchResultCondition() {
final Component base = Component.text("get the set the get the set the get the set");

final Component replaced = base.replaceText(c -> c.match("[gs]et")
.condition((result, count, replacements) -> result.group().equals("set") ? PatternReplacementResult.REPLACE : PatternReplacementResult.CONTINUE)
.replacement("pet"));

final Component expected = Component.text().content("get the ")
.append(
Component.text("pet"),
Component.text(" the get the "),
Component.text("pet"),
Component.text(" the get the "),
Component.text("pet")
)
.build();
assertEquals(expected, replaced);
}
}

0 comments on commit a963b70

Please sign in to comment.