/** * Returns a converter based on <i>existing</i> forward and backward functions. Note that it is * unnecessary to create <i>new</i> classes implementing {@code Function} just to pass them in * here. Instead, simply subclass {@code Converter} and implement its {@link #doForward} and * {@link #doBackward} methods directly. * * <p>These functions will never be passed {@code null} and must not under any circumstances * return {@code null}. If a value cannot be converted, the function should throw an unchecked * exception (typically, but not necessarily, {@link IllegalArgumentException}). * * <p>The returned converter is serializable if both provided functions are. * * @since 17.0 */ public static <A, B> Converter<A, B> from( Function<? super A, ? extends B> forwardFunction, Function<? super B, ? extends A> backwardFunction) { return from(forwardFunction, backwardFunction, "Converter.from(" + forwardFunction + ", " + backwardFunction + ")"); }
@Override public A revertNonNull(B b) { return original.convertNonNull(b); }
@Override public A revertNonNull(C c) { return first.revertNonNull(second.revertNonNull(c)); }
@Override public R modify(Function<? super R, ? extends R> mutator) { Objects.requireNonNull(mutator); Box.Nullable<R> result = Box.Nullable.of(null); delegate.modify(input -> { R unmappedResult = mutator.apply(converter.convertNonNull(input)); result.set(unmappedResult); return converter.revertNonNull(unmappedResult); }); return result.get(); }
@Override protected A doForward(B b) { return original.correctedDoBackward(b); }
@Override protected B doBackward(A a) { return original.correctedDoForward(a); }
/** * Returns a representation of {@code a} as an instance of type {@code B}, using * the type system (and not null checks) to ensure that input and output are non-null. */ public final B convertNonNull(A a) { return requireNonNull(doForward(requireNonNull(a))); }
/** * Returns a representation of {@code b} as an instance of type {@code A}, using * the type system (and not null checks) to ensure that input and output are non-null. */ public final A revertNonNull(B b) { return requireNonNull(doBackward(requireNonNull(b))); }
/** * Returns a converter whose {@code convert} method applies {@code secondConverter} to the result * of this converter. Its {@code reverse} method applies the converters in reverse order. * * <p>The returned converter is serializable if {@code this} converter and {@code secondConverter} * are. */ public final <C> Converter<A, C> andThen(Converter<B, C> secondConverter) { return doAndThen(secondConverter); }
/** * @deprecated Provided to satisfy the {@code Function} interface; use {@link #convert} instead. */ @Deprecated @Override @Nullable public final B apply(@Nullable A a) { return convert(a); }
/** Shortcut for doing a set() on the result of a get(). */ @Override public R modify(Function<? super R, ? extends R> mutator) { Box.Nullable<R> result = Box.Nullable.of(null); delegate.modify(input -> { R unmappedResult = mutator.apply(converter.convertNonNull(input)); result.set(unmappedResult); return converter.revertNonNull(unmappedResult); }); return result.get(); }
@Override @Nullable A correctedDoBackward(@Nullable C c) { return first.correctedDoBackward(second.correctedDoBackward(c)); }
@Override @Nullable C correctedDoForward(@Nullable A a) { return second.correctedDoForward(first.correctedDoForward(a)); }
@Nullable B correctedDoForward(@Nullable A a) { return a == null ? null : requireNonNull(doForward(a)); }
@Nullable A correctedDoBackward(@Nullable B b) { return b == null ? null : requireNonNull(doBackward(b)); }
/** Uses a `Converter<T, R>` to generate a `Converter<Optional<T>, Optional<R>>`. */ public static <T, R> Converter<Optional<T>, Optional<R>> perElementConverterOpt(ConverterNullable<T, R> perElement) { Objects.requireNonNull(perElement); return Converter.from( optT -> optT.map(perElement::convert), optR -> optR.map(perElement::revert), "perElement=" + perElement); }
@Override public C convertNonNull(A a) { return second.convertNonNull(first.convertNonNull(a)); }
@Override public B convertNonNull(A a) { return original.revertNonNull(a); }
/** * Returns a representation of {@code b} as an instance of type {@code A}. * * @return the converted value; is null <i>if and only if</i> {@code b} is null */ @Nullable public final A revert(@Nullable B b) { return correctedDoBackward(b); }
/** * Returns a representation of {@code a} as an instance of type {@code B}. * * @return the converted value; is null <i>if and only if</i> {@code a} is null */ @Nullable public final B convert(@Nullable A a) { return correctedDoForward(a); }