package net.minecraft.command.type.management; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.command.arg.CommandArg; public abstract class Converter<F, T, E extends CommandException> { public abstract T convert(F toConvert) throws E; public static <F, T, FT, E extends CommandException> Converter<F, FT, E> chain(final Converter<F, T, ? extends E> converter, final Converter<T, FT, ? extends E> newConverter) { return new Converter<F, FT, E>() { @Override public final FT convert(final F toConvert) throws E { return newConverter.convert(converter.convert(toConvert)); } }; } public <FT> Converter<F, FT, E> chain(final Converter<T, FT, ? extends E> newConverter) { return new Converter<F, FT, E>() { @Override public final FT convert(final F toConvert) throws E { return newConverter.convert(Converter.this.convert(toConvert)); } }; } public static final <F extends T, T> SConverter<F, T> primitiveConverter() { return new SConverter<F, T>() { @Override public T convert(final F toConvert) { return toConvert; } }; } public static class Chained<F, T, E extends CommandException> { private final Convertable<F, ?, E> baseType; private final Convertable<T, ?, ? extends E> type; private final Converter<F, T, ? extends E> converter; public Chained(final Convertable<F, ?, E> baseType, final Convertable<T, ?, ? extends E> type, final Converter<F, T, ? extends E> converter) { this.baseType = baseType; this.type = type; this.converter = converter; } public Chained(final Convertable<F, ?, E> from, final Convertable<T, ?, ? extends E> to) { final Converter<F, T, ? extends E> converter = from.getConverter(to); if (converter == null) throw new IllegalArgumentException("No converter from " + from.name + " to " + to.name + " known."); this.baseType = from; this.type = to; this.converter = converter; } public static <F, T, FT, E extends CommandException> Chained<F, FT, E> chain(final Chained<F, T, E> base, final Convertable<FT, ?, ? extends E> newType) { final Converter<T, FT, ? extends E> toChain = base.type.getConverter(newType); if (toChain == null) throw new IllegalArgumentException("No converter from " + base.type.name + " to " + newType.name + " known."); return new Chained<F, FT, E>(base.baseType, newType, Converter.<F, T, FT, E> chain(base.converter, toChain)); } public <FT> Chained<F, FT, E> chain(final Convertable<FT, ?, ? extends E> newType) { final Converter<T, FT, ? extends E> toChain = this.type.getConverter(newType); if (toChain == null) throw new IllegalArgumentException("No converter from " + this.type.name + " to " + newType.name + " known."); return new Chained<>(this.baseType, newType, Converter.chain(this.converter, toChain)); } public void register() { this.baseType.addConverter(this.type, this.converter); } } public CommandArg<T> transform(final CommandArg<F> toTransform) { return new CommandArg<T>() { @Override public T eval(final ICommandSender sender) throws CommandException { return Converter.this.convert(toTransform.eval(sender)); } }; } }