package bjc.utils.patterns; import java.util.function.*; import bjc.functypes.*; /** * Represents a pattern matcher against a series of patterns. * * @author Ben Culkin * * @param The type returned from matching the patterns. * @param The type to match against. */ @FunctionalInterface public interface IPatternMatcher { /** * Match an input object against a set of patterns. * * @param input The object to match against. * * @return The result of matching against the object. * * @throws NonExhaustiveMatch If none of the patterns in this set match */ ReturnType matchFor(InputType input) throws NonExhaustiveMatch; /** * Create a pattern matcher against a static set of patterns. * * @param The type returned from matching the patterns. * @param The type to match against. * * @param patterns The set of patterns to match on. * * @return A pattern matcher which matches on the given patterns. */ @SafeVarargs static IPatternMatcher matchingOn( ComplexPattern... patterns) { return new PatternMatcher<>(patterns); } /** * Create a pattern matcher from a handler function. * * @param The type returned by the matcher. * @param The type to match against. * * @param handler The handler function. * * @return A pattern matcher defined by the given handler. */ static IPatternMatcher from( ThrowFunction handler) { return new FunctionalPatternMatcher<>(handler); } /** * Create a pattern matcher which applies a transform to its input. * * @param The new input type to use. * @param transformer The function to convert from the new input to the old input. * * @return A pattern matcher which takes values of the new type instead. */ default IPatternMatcher transformInput( Function transformer) { return from(inp -> matchFor(transformer.apply(inp))); } /** * Create a pattern matcher which applies a transform to its output. * * @param The new output type to use. * * @param transformer The function to convert from the new output to the old output. * * @return A pattern matcher which takes values of the new type instead. */ default IPatternMatcher transformOutput( Function transformer) { return from(inp -> transformer.apply(matchFor(inp))); } }