Skip to content

Commit

Permalink
Add support for implicit conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
rchomczyk committed Oct 27, 2024
1 parent bf23e39 commit 3b26450
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions honey-common/src/dev/shiza/honey/Honey.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.shiza.honey;

import dev.shiza.honey.conversion.ImplicitConversion;
import dev.shiza.honey.message.Message;
import dev.shiza.honey.message.MessageCompiler;
import dev.shiza.honey.placeholder.evaluator.PlaceholderContext;
Expand All @@ -15,13 +16,15 @@ public interface Honey<T> {

static <T> Honey<T> create(
final MessageCompiler<T> messageCompiler,
final ImplicitConversion implicitConversion,
final PlaceholderContext placeholderContext,
final PlaceholderResolver placeholderResolver,
final PlaceholderSanitizer placeholderSanitizer,
final PlaceholderEvaluator placeholderEvaluator,
final ProcessorRegistry processorRegistry) {
return new HoneyImpl<>(
messageCompiler,
implicitConversion,
placeholderContext,
placeholderResolver,
placeholderSanitizer,
Expand Down
25 changes: 24 additions & 1 deletion honey-common/src/dev/shiza/honey/HoneyImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static java.util.Collections.emptyList;
import static java.util.concurrent.CompletableFuture.completedFuture;

import dev.shiza.honey.conversion.ImplicitConversion;
import dev.shiza.honey.message.Message;
import dev.shiza.honey.message.MessageCompiler;
import dev.shiza.honey.placeholder.evaluator.EvaluatedPlaceholder;
Expand All @@ -16,6 +17,7 @@
import dev.shiza.honey.placeholder.visitor.PlaceholderVisitorImpl;
import dev.shiza.honey.placeholder.visitor.PromisingPlaceholderVisitor;
import dev.shiza.honey.processor.ProcessorRegistry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand All @@ -25,6 +27,7 @@
public class HoneyImpl<T> implements Honey<T> {

private final MessageCompiler<T> messageCompiler;
private final ImplicitConversion implicitConversion;
private final PlaceholderContext placeholderContext;
private final PlaceholderResolver placeholderResolver;
private final PlaceholderSanitizer placeholderSanitizer;
Expand All @@ -33,12 +36,14 @@ public class HoneyImpl<T> implements Honey<T> {

protected HoneyImpl(
final MessageCompiler<T> messageCompiler,
final ImplicitConversion implicitConversion,
final PlaceholderContext placeholderContext,
final PlaceholderResolver placeholderResolver,
final PlaceholderSanitizer placeholderSanitizer,
final PlaceholderEvaluator placeholderEvaluator,
final ProcessorRegistry processorRegistry) {
this.messageCompiler = messageCompiler;
this.implicitConversion = implicitConversion;
this.placeholderContext = placeholderContext;
this.placeholderResolver = placeholderResolver;
this.placeholderSanitizer = placeholderSanitizer;
Expand Down Expand Up @@ -99,7 +104,25 @@ private T compile(final Message message, final List<SanitizedPlaceholder> placeh
final String processedContent = processorRegistry.preprocess(message.content());
final String sanitizedContent =
placeholderSanitizer.getSanitizedContent(processedContent, placeholders);
return messageCompiler.compile(sanitizedContent, placeholders);
return messageCompiler.compile(sanitizedContent, convertPlaceholders(placeholders));
}

private List<SanitizedPlaceholder> convertPlaceholders(
final List<SanitizedPlaceholder> placeholders) {
if (implicitConversion == null) {
return placeholders;
}

final List<SanitizedPlaceholder> convertedPlaceholders = new ArrayList<>();
for (final SanitizedPlaceholder placeholder : placeholders) {
convertedPlaceholders.add(
new SanitizedPlaceholder(
placeholder.key(),
placeholder.expression(),
implicitConversion.convert(placeholder.evaluatedValue())));
}

return convertedPlaceholders;
}

private CompletableFuture<List<EvaluatedPlaceholder>> unwrapPromisedValues(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;

import dev.shiza.honey.Honey;
import dev.shiza.honey.conversion.ImplicitConversion;
import dev.shiza.honey.message.MessageCompiler;
import dev.shiza.honey.placeholder.evaluator.PlaceholderContext;
import dev.shiza.honey.placeholder.evaluator.PlaceholderEvaluator;
import dev.shiza.honey.placeholder.resolver.PlaceholderResolver;
import dev.shiza.honey.placeholder.sanitizer.PlaceholderSanitizer;
import dev.shiza.honey.processor.ProcessorRegistry;
import dev.shiza.honey.reflection.ReflectivePlaceholderEvaluatorFactory;
import java.util.Collections;
import java.util.Map;
import java.util.function.Consumer;
import net.kyori.adventure.text.Component;
Expand All @@ -29,22 +31,25 @@ static AdventureHoney createReflective(
final MiniMessage miniMessage, final PlaceholderContext placeholderContext) {
return create(
AdventureMessageCompilerFactory.create(miniMessage),
ImplicitConversion.create(Collections.emptySet()),
placeholderContext,
PlaceholderResolver.create(),
PlaceholderSanitizer.create(),
ReflectivePlaceholderEvaluatorFactory.create(),
ProcessorRegistry.create());
}

private static AdventureHoney create(
static AdventureHoney create(
final MessageCompiler<Component> messageCompiler,
final ImplicitConversion implicitConversion,
final PlaceholderContext placeholderContext,
final PlaceholderResolver placeholderResolver,
final PlaceholderSanitizer placeholderSanitizer,
final PlaceholderEvaluator placeholderEvaluator,
final ProcessorRegistry processorRegistry) {
return new AdventureHoneyImpl(
messageCompiler,
implicitConversion,
placeholderContext,
placeholderResolver,
placeholderSanitizer,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.shiza.honey.adventure;

import dev.shiza.honey.HoneyImpl;
import dev.shiza.honey.conversion.ImplicitConversion;
import dev.shiza.honey.message.MessageCompiler;
import dev.shiza.honey.placeholder.evaluator.PlaceholderContext;
import dev.shiza.honey.placeholder.evaluator.PlaceholderEvaluator;
Expand All @@ -15,13 +16,15 @@ class AdventureHoneyImpl extends HoneyImpl<Component> implements AdventureHoney

AdventureHoneyImpl(
final MessageCompiler<Component> messageCompiler,
final ImplicitConversion implicitConversion,
final PlaceholderContext placeholderContext,
final PlaceholderResolver placeholderResolver,
final PlaceholderSanitizer placeholderSanitizer,
final PlaceholderEvaluator placeholderEvaluator,
final ProcessorRegistry processorRegistry) {
super(
messageCompiler,
implicitConversion,
placeholderContext,
placeholderResolver,
placeholderSanitizer,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package dev.shiza.honey.conversion;

import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

public final class ImplicitConversion {

private final Map<Class<?>, Function<Object, Object>> conversions;

ImplicitConversion(final Set<ImplicitConversionUnit> units) {
this.conversions =
units.stream()
.collect(
Collectors.toMap(ImplicitConversionUnit::from, ImplicitConversionUnit::conversion));
}

public static ImplicitConversion create(final Set<ImplicitConversionUnit> units) {
return new ImplicitConversion(units);
}

public <T> T convert(final Object value) {
Object currentValue = value;

boolean conversionFound;
do {
conversionFound = false;
for (final Map.Entry<Class<?>, Function<Object, Object>> entry : conversions.entrySet()) {
if (entry.getKey().isAssignableFrom(currentValue.getClass())) {
final Object convertedValue = entry.getValue().apply(currentValue);
if (convertedValue != null) {
currentValue = convertedValue;
conversionFound = true;
break;
}
}
}
} while (conversionFound);

return (T) currentValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.shiza.honey.conversion;

public final class ImplicitConversionException extends IllegalStateException {

public ImplicitConversionException(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package dev.shiza.honey.conversion;

import java.util.function.Function;

public record ImplicitConversionUnit(
Class<?> from, Class<?> into, Function<Object, Object> conversion) {

public static <T, R> ImplicitConversionUnit unchecked(
final Class<T> from, final Class<R> into, final Function<T, R> conversion) {
if (from == null || into == null || conversion == null) {
throw new ImplicitConversionException(
"Cannot create an implicit conversion unit with null values.");
}

if (from.equals(into)) {
throw new ImplicitConversionException("Cannot create an recursive conversion unit.");
}

return new ImplicitConversionUnit(from, into, (Function<Object, Object>) conversion);
}
}
4 changes: 4 additions & 0 deletions honey-common/src/dev/shiza/honey/conversion/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@Experimental
package dev.shiza.honey.conversion;

import org.jetbrains.annotations.ApiStatus.Experimental;

0 comments on commit 3b26450

Please sign in to comment.