├── .gitignore ├── LICENSE ├── README.md ├── benchmarks ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── leacox │ └── motif │ └── benchmarks │ ├── Benchmark.java │ ├── FactorialBenchmark.java │ └── FizzBuzzBenchmark.java ├── checkstyle.xml ├── examples ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── leacox │ └── motif │ └── example │ ├── CaseThatExample.java │ ├── FactorialExample.java │ └── superhero │ ├── Character.java │ ├── Civilian.java │ ├── SuperHero.java │ └── SuperHeroExample.java ├── generator ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── leacox │ └── motif │ ├── cases │ ├── Case1CasesGenerator.java │ ├── Case2CasesGenerator.java │ ├── Case3CasesGenerator.java │ ├── Copyright.java │ ├── ListConsCasesGenerator.java │ ├── OptionalCasesGenerator.java │ ├── PrimitiveCasesGenerator.java │ ├── Tuple1CasesGenerator.java │ ├── Tuple2CasesGenerator.java │ └── Tuple3CasesGenerator.java │ └── generate │ ├── BaseMatchMethodPermutationBuilder.java │ ├── CasesGenerator.java │ ├── Match0MethodPermutationBuilder.java │ ├── Match0MethodSpec.java │ ├── Match1MethodPermutationBuilder.java │ ├── Match1MethodSpec.java │ ├── Match2MethodPermutationBuilder.java │ ├── Match2MethodSpec.java │ ├── Match3MethodPermutationBuilder.java │ ├── Match3MethodSpec.java │ ├── MatchType.java │ ├── MethodParam.java │ └── TypeNameWithArity.java ├── hamcrest ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── leacox │ │ └── motif │ │ └── hamcrest │ │ └── CaseThatCases.java │ └── test │ └── java │ └── com │ └── leacox │ └── motif │ └── hamcrest │ └── CaseThatCasesSpec.java ├── motif ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── leacox │ │ └── motif │ │ ├── MatchException.java │ │ ├── MatchesAny.java │ │ ├── MatchesExact.java │ │ ├── Motif.java │ │ ├── caseclass │ │ ├── Case1.java │ │ ├── Case2.java │ │ └── Case3.java │ │ ├── cases │ │ ├── Case1Cases.java │ │ ├── Case1Extractor.java │ │ ├── Case1FieldExtractor.java │ │ ├── Case2Cases.java │ │ ├── Case2Extractor.java │ │ ├── Case2FieldExtractor.java │ │ ├── Case3Cases.java │ │ ├── Case3Extractor.java │ │ ├── Case3FieldExtractor.java │ │ ├── ListConsCases.java │ │ ├── ListConsHeadExtractor.java │ │ ├── ListConsHeadFieldExtractor.java │ │ ├── ListConsHeadTailExtractor.java │ │ ├── ListConsHeadTailFieldExtractor.java │ │ ├── ListConsNilExtractor.java │ │ ├── ListConsNilFieldExtractor.java │ │ ├── OptionalCases.java │ │ ├── OptionalExtractor.java │ │ ├── OptionalFieldExtractor.java │ │ ├── OptionalNoneExtractor.java │ │ ├── OptionalNoneFieldExtractor.java │ │ ├── PrimitiveCases.java │ │ ├── PrimitiveExtractor.java │ │ ├── PrimitiveFieldExtractor.java │ │ ├── Tuple1Cases.java │ │ ├── Tuple1Extractor.java │ │ ├── Tuple1FieldExtractor.java │ │ ├── Tuple2Cases.java │ │ ├── Tuple2Extractor.java │ │ ├── Tuple2FieldExtractor.java │ │ ├── Tuple3Cases.java │ │ ├── Tuple3Extractor.java │ │ ├── Tuple3FieldExtractor.java │ │ └── TypeOfCases.java │ │ ├── extract │ │ ├── DecomposableMatch0.java │ │ ├── DecomposableMatch1.java │ │ ├── DecomposableMatch2.java │ │ ├── DecomposableMatch3.java │ │ ├── DecomposableMatchBuilder.java │ │ ├── DecomposableMatchBuilder0.java │ │ ├── DecomposableMatchBuilder1.java │ │ ├── DecomposableMatchBuilder2.java │ │ ├── DecomposableMatchBuilder3.java │ │ ├── Extractor0.java │ │ ├── Extractor1.java │ │ ├── Extractor2.java │ │ ├── Extractor3.java │ │ ├── FieldExtractor.java │ │ ├── NestedFieldExtractor.java │ │ ├── NestedMatchers.java │ │ ├── matchers │ │ │ ├── Any.java │ │ │ ├── ArgumentMatchers.java │ │ │ ├── Equals.java │ │ │ └── Matcher.java │ │ └── util │ │ │ ├── Lists.java │ │ │ └── Maps.java │ │ ├── function │ │ ├── Consumer0.java │ │ ├── Consumer2.java │ │ ├── Consumer3.java │ │ ├── Function2.java │ │ └── Function3.java │ │ ├── matching │ │ ├── ConsumablePattern.java │ │ ├── FluentMatching.java │ │ ├── FluentMatchingC.java │ │ ├── FluentMatchingR.java │ │ ├── IdentityFieldExtractor.java │ │ ├── InitialMatching0.java │ │ ├── InitialMatching1.java │ │ ├── InitialMatching2.java │ │ ├── InitialMatching3.java │ │ ├── Matching0.java │ │ ├── Matching1.java │ │ ├── Matching2.java │ │ ├── Matching3.java │ │ ├── OngoingMatchingC0.java │ │ ├── OngoingMatchingC1.java │ │ ├── OngoingMatchingC2.java │ │ ├── OngoingMatchingC3.java │ │ ├── OngoingMatchingR0.java │ │ ├── OngoingMatchingR1.java │ │ ├── OngoingMatchingR2.java │ │ ├── OngoingMatchingR3.java │ │ └── Pattern.java │ │ └── tuple │ │ ├── Tuple.java │ │ ├── Tuple1.java │ │ ├── Tuple2.java │ │ └── Tuple3.java │ └── test │ └── java │ └── com │ └── leacox │ └── motif │ ├── cases │ ├── Animal.java │ ├── CaseClassCasesSpec.java │ ├── Consuming.java │ ├── ListConsCasesSpec.java │ ├── NestedCasesSpec.java │ ├── NotAnimal.java │ ├── OptionalCasesSpec.java │ ├── PrimitiveCasesSpec.java │ ├── Tuple2CasesSpec.java │ ├── Tuple3CasesSpec.java │ ├── Tuple3CasesTests.java │ └── TypeOfCasesSpec.java │ └── tuple │ └── Tuple2Spec.java ├── pom.xml └── suppressions.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings 4 | eclipsebin 5 | 6 | bin 7 | gen 8 | build 9 | out 10 | lib 11 | 12 | target 13 | pom.xml.* 14 | release.properties 15 | 16 | .idea 17 | *.iml 18 | *.ipr 19 | *.iws 20 | classes 21 | 22 | obj 23 | 24 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Motif 2 | ===== 3 | 4 | A pattern matching library for Java 8. Motif provides scala-like pattern matching in Java 8. 5 | 6 | ## Examples 7 | 8 | ### FizzBuzz 9 | 10 | ```java 11 | IntStream.range(0, 101).forEach( 12 | n -> System.out.println( 13 | match(Tuple2.of(n % 3, n % 5)) 14 | .when(tuple2(eq(0), eq(0))).get(() -> "FizzBuzz") 15 | .when(tuple2(eq(0), any())).get(y -> "Fizz") 16 | .when(tuple2(any(), eq(0))).get(x -> "Buzz") 17 | .orElse(String.valueOf(n)) 18 | .getMatch() 19 | ) 20 | ); 21 | ``` 22 | 23 | ### Optional 24 | 25 | ```java 26 | Optional personOpt = getPerson(); 27 | match(personOpt) 28 | .when(some(any())).then(person -> doStuff(person)) 29 | .when(none()).then(() -> System.out.println("Person not found")) 30 | .doMatch(); 31 | ``` 32 | 33 | ### Factorial 34 | 35 | ```java 36 | public long factorial(long i) { 37 | return match(i) 38 | .when(eq(0)).get(() -> 1l) 39 | .when(any()).get(x -> x * factorial(x - 1)) 40 | .getMatch(); 41 | } 42 | ``` 43 | 44 | ### Nested Matching 45 | 46 | ```java 47 | Optional> opt = Optional.of(Tuple2.of("first", "second")); 48 | match(opt) 49 | .when(some(tuple2(eq("third"), any()))).then(b -> doStuff(b)) 50 | .when(some(tuple2(any(), eq("second")))).then(a -> doStuff(a)) 51 | .when(none()).then(() -> System.out.println("Tuple not found")) 52 | .doMatch(); 53 | ``` 54 | 55 | ### List Cons Matching 56 | 57 | ```java 58 | List list = Arrays.asList("a", "b", "c", "d"); 59 | match(list) 60 | .when(nil()).then(() -> System.out.println("Empty List")) 61 | .when(headNil(eq("b"))).then(() -> System.out.println("Singleton List of 'b'")) 62 | .when(headNil(any())).then(head -> System.out.println("Singleton List of " + head)) 63 | .when(headTail(any(), any())).then( 64 | (head, tail) -> System.out.println("head: " + head + " Remaining: " + tail)) 65 | .doMatch(); 66 | ``` 67 | 68 | ## Download 69 | 70 | Download the latest JAR via Maven: 71 | 72 | ```xml 73 | 74 | com.leacox.motif 75 | motif 76 | 0.1 77 | 78 | ``` 79 | 80 | ## License 81 | 82 | Copyright 2015 John Leacox 83 | 84 | Licensed under the Apache License, Version 2.0 (the "License"); 85 | you may not use this file except in compliance with the License. 86 | You may obtain a copy of the License at 87 | 88 | http://www.apache.org/licenses/LICENSE-2.0 89 | 90 | Unless required by applicable law or agreed to in writing, software 91 | distributed under the License is distributed on an "AS IS" BASIS, 92 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 93 | See the License for the specific language governing permissions and 94 | limitations under the License. 95 | -------------------------------------------------------------------------------- /benchmarks/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | com.leacox.motif 9 | motif-parent 10 | 1.0-SNAPSHOT 11 | 12 | 13 | motif-benchmarks 14 | 15 | 16 | 17 | com.leacox.motif 18 | motif 19 | ${project.version} 20 | 21 | 22 | org.openjdk.jmh 23 | jmh-core 24 | 25 | 26 | org.openjdk.jmh 27 | jmh-generator-annprocess 28 | provided 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.codehaus.mojo 36 | exec-maven-plugin 37 | 1.4.0 38 | 39 | 40 | 41 | java 42 | 43 | 44 | 45 | 46 | java 47 | 48 | -classpath 49 | 50 | com.leacox.motif.benchmarks.Benchmark 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/leacox/motif/benchmarks/Benchmark.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.benchmarks; 18 | 19 | import org.openjdk.jmh.runner.Runner; 20 | import org.openjdk.jmh.runner.RunnerException; 21 | import org.openjdk.jmh.runner.options.Options; 22 | import org.openjdk.jmh.runner.options.OptionsBuilder; 23 | 24 | /** 25 | * Benchmarks of motif vs traditional Java. 26 | * 27 | * @author John Leacox 28 | */ 29 | public class Benchmark { 30 | /** 31 | * Main method to execute benchmarks. 32 | */ 33 | public static void main(String[] args) throws RunnerException { 34 | Options opt = new OptionsBuilder() 35 | .include(FactorialBenchmark.class.getSimpleName()) 36 | .include(FizzBuzzBenchmark.class.getSimpleName()) 37 | .forks(1) 38 | .build(); 39 | 40 | new Runner(opt).run(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/leacox/motif/benchmarks/FactorialBenchmark.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.benchmarks; 18 | 19 | import static com.leacox.motif.MatchesAny.any; 20 | import static com.leacox.motif.MatchesExact.eq; 21 | import static com.leacox.motif.Motif.match; 22 | 23 | import org.openjdk.jmh.annotations.Benchmark; 24 | import org.openjdk.jmh.annotations.BenchmarkMode; 25 | import org.openjdk.jmh.annotations.Mode; 26 | import org.openjdk.jmh.annotations.OutputTimeUnit; 27 | import org.openjdk.jmh.annotations.Param; 28 | import org.openjdk.jmh.annotations.Scope; 29 | import org.openjdk.jmh.annotations.State; 30 | 31 | import java.util.concurrent.TimeUnit; 32 | 33 | /** 34 | * Factorial benchmarks. 35 | * 36 | * @author John Leacox 37 | */ 38 | @State(Scope.Thread) 39 | @BenchmarkMode(Mode.AverageTime) 40 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 41 | public class FactorialBenchmark { 42 | @Param({"0", "1", "10"}) 43 | public int n; 44 | 45 | /** 46 | * Factorial benchmark using a conditional. 47 | */ 48 | @Benchmark 49 | public long factorialConditional() { 50 | return factConditionl(n); 51 | } 52 | 53 | private long factConditionl(long i) { 54 | if (i == 0) { 55 | return 1; 56 | } else { 57 | return i * factConditionl(i - 1); 58 | } 59 | } 60 | 61 | /** 62 | * Factorial benchmark using motif pattern matching. 63 | */ 64 | @Benchmark 65 | public long factorialPatternMatching() { 66 | return factMatching(n); 67 | } 68 | 69 | private long factMatching(long i) { 70 | return match(i) 71 | .when(eq(0L)).get(() -> 1L) 72 | .when(any()).get(x -> x * factMatching(x - 1)) 73 | .getMatch(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /benchmarks/src/main/java/com/leacox/motif/benchmarks/FizzBuzzBenchmark.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.benchmarks; 18 | 19 | import static com.leacox.motif.MatchesAny.any; 20 | import static com.leacox.motif.MatchesExact.eq; 21 | import static com.leacox.motif.Motif.match; 22 | import static com.leacox.motif.cases.Tuple2Cases.tuple2; 23 | 24 | import com.leacox.motif.tuple.Tuple2; 25 | 26 | import org.openjdk.jmh.annotations.Benchmark; 27 | import org.openjdk.jmh.annotations.BenchmarkMode; 28 | import org.openjdk.jmh.annotations.Mode; 29 | import org.openjdk.jmh.annotations.OutputTimeUnit; 30 | import org.openjdk.jmh.annotations.Scope; 31 | import org.openjdk.jmh.annotations.State; 32 | 33 | import java.util.concurrent.TimeUnit; 34 | import java.util.stream.IntStream; 35 | 36 | /** 37 | * Fizzbuzz benchmarks. 38 | * 39 | * @author John Leacox 40 | */ 41 | @State(Scope.Thread) 42 | @BenchmarkMode(Mode.AverageTime) 43 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 44 | public class FizzBuzzBenchmark { 45 | /** 46 | * Fizzbuzz benchmark using a conditional. 47 | */ 48 | @Benchmark 49 | public void fizzbuzzConditional() { 50 | 51 | IntStream.range(0, 101).forEach( 52 | n -> { 53 | if (n % (3 * 5) == 0) { 54 | System.out.println("FizzBuzz"); 55 | } else if (n % 3 == 0) { 56 | System.out.println("Fizz"); 57 | } else if (n % 5 == 0) { 58 | System.out.println("Buzz"); 59 | } else { 60 | System.out.println(n); 61 | } 62 | } 63 | ); 64 | } 65 | 66 | /** 67 | * Fizzbuzz benchmark using motif pattern matching. 68 | */ 69 | @Benchmark 70 | public void fizzBuzzPatternMatching() { 71 | IntStream.range(0, 101).forEach( 72 | n -> System.out.println( 73 | match(Tuple2.of(n % 3, n % 5)) 74 | .when(tuple2(eq(0), eq(0))).get(() -> "FizzBuzz") 75 | .when(tuple2(eq(0), any())).get(y -> "Fizz") 76 | .when(tuple2(any(), eq(0))).get(x -> "Buzz") 77 | .orElse(String.valueOf(n)) 78 | .getMatch() 79 | ) 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /examples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.leacox.motif 8 | motif-parent 9 | 1.0-SNAPSHOT 10 | 11 | 12 | motif-examples 13 | 14 | 15 | 16 | com.google.auto.value 17 | auto-value 18 | 19 | 20 | com.leacox.motif 21 | motif 22 | ${project.version} 23 | 24 | 25 | com.leacox.motif 26 | motif-hamcrest 27 | ${project.version} 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /examples/src/main/java/com/leacox/motif/example/CaseThatExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.example; 18 | 19 | import static com.leacox.motif.Motif.match; 20 | import static com.leacox.motif.hamcrest.CaseThatCases.caseEq; 21 | 22 | /** 23 | * An example of using a hamcrest matcher with motif pattern matching. 24 | * 25 | * @author John Leacox 26 | */ 27 | public class CaseThatExample { 28 | /** 29 | * A main method to run the hamcrest example. 30 | */ 31 | public static void main(String[] args) { 32 | new CaseThatExample().run(); 33 | } 34 | 35 | private void run() { 36 | Object pi = Math.PI; 37 | 38 | String result = match(pi) 39 | .when(caseEq(42)).get(t -> "a magic no.") 40 | .when(caseEq("Hello!")).get(t -> "a greet") 41 | .when(caseEq(Math.PI)).get(t -> "another magic no.") 42 | .orElse("something else") 43 | .getMatch(); 44 | 45 | System.out.println("Matching Result: " + result); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/src/main/java/com/leacox/motif/example/FactorialExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.example; 18 | 19 | import static com.leacox.motif.MatchesAny.any; 20 | import static com.leacox.motif.Motif.match; 21 | import static com.leacox.motif.cases.PrimitiveCases.caseLong; 22 | 23 | /** 24 | * An example of using pattern matching for implementing factorial. 25 | * 26 | * @author John Leacox 27 | */ 28 | public class FactorialExample { 29 | /** 30 | * A traditional implementation of factorial with a conditional. 31 | */ 32 | public long factConditional(long n) { 33 | if (n == 0) { 34 | return 1; 35 | } else { 36 | return n * factConditional(n - 1); 37 | } 38 | } 39 | 40 | /** 41 | * An implementation of factorial using motif pattern matching. 42 | */ 43 | public long factMatching(long n) { 44 | return match(n) 45 | .when(caseLong(0)).get(() -> 1L) 46 | .when(caseLong(any())).get(i -> i * factMatching(i - 1)) 47 | .getMatch(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /examples/src/main/java/com/leacox/motif/example/superhero/Character.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.example.superhero; 18 | 19 | /** 20 | * A character with a name. 21 | * 22 | * @author John Leacox 23 | */ 24 | public interface Character { 25 | String name(); 26 | } 27 | -------------------------------------------------------------------------------- /examples/src/main/java/com/leacox/motif/example/superhero/Civilian.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.example.superhero; 18 | 19 | import com.leacox.motif.caseclass.Case2; 20 | import com.leacox.motif.tuple.Tuple2; 21 | 22 | import com.google.auto.value.AutoValue; 23 | 24 | import java.math.BigDecimal; 25 | 26 | /** 27 | * A civilian character. 28 | * 29 | * @author John Leacox 30 | */ 31 | @AutoValue 32 | public abstract class Civilian implements Case2, Character { 33 | /** 34 | * Creates a new instance of {@link Civilian}. 35 | */ 36 | public static Civilian create(String name, BigDecimal wealth) { 37 | return new AutoValue_Civilian(name, wealth); 38 | } 39 | 40 | @Override 41 | public Tuple2 extract() { 42 | return Tuple2.of(name(), wealth()); 43 | } 44 | 45 | public abstract String name(); 46 | 47 | public abstract BigDecimal wealth(); 48 | } 49 | -------------------------------------------------------------------------------- /examples/src/main/java/com/leacox/motif/example/superhero/SuperHero.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.example.superhero; 18 | 19 | import com.leacox.motif.caseclass.Case3; 20 | import com.leacox.motif.tuple.Tuple3; 21 | 22 | import com.google.auto.value.AutoValue; 23 | 24 | import java.util.List; 25 | import java.util.Optional; 26 | 27 | /** 28 | * A superhero character. 29 | * 30 | * @author John Leacox 31 | */ 32 | @AutoValue 33 | public abstract class SuperHero 34 | implements Case3, Optional>, Character { 35 | /** 36 | * Creates a new instance of {@link SuperHero}. 37 | */ 38 | public static SuperHero create(String name, List powers, Optional alterEgo) { 39 | return new AutoValue_SuperHero(name, powers, alterEgo); 40 | } 41 | 42 | @Override 43 | public Tuple3, Optional> extract() { 44 | return Tuple3.of(name(), powers(), alterEgo()); 45 | } 46 | 47 | public abstract String name(); 48 | 49 | public abstract List powers(); 50 | 51 | public abstract Optional alterEgo(); 52 | } 53 | -------------------------------------------------------------------------------- /examples/src/main/java/com/leacox/motif/example/superhero/SuperHeroExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.example.superhero; 18 | 19 | import static com.leacox.motif.MatchesAny.any; 20 | import static com.leacox.motif.MatchesExact.eq; 21 | import static com.leacox.motif.Motif.match; 22 | import static com.leacox.motif.cases.Case2Cases.case2; 23 | import static com.leacox.motif.cases.Case3Cases.case3; 24 | 25 | import java.math.BigDecimal; 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | import java.util.Optional; 29 | 30 | /** 31 | * An example of case class matching with nested extraction. 32 | * 33 | * @author John Leacox 34 | */ 35 | public class SuperHeroExample { 36 | /** 37 | * Main method that runs the example. 38 | */ 39 | public static void main(String[] args) { 40 | new SuperHeroExample().run(); 41 | } 42 | 43 | private void run() { 44 | List powers = new ArrayList<>(); 45 | powers.add("Awesome Suit"); 46 | powers.add("Flying"); 47 | 48 | Civilian tonyStark = Civilian.create("Tony Stark", new BigDecimal(9838439287473L)); 49 | 50 | Character ironMan = SuperHero.create("IronMan", powers, Optional.of(tonyStark)); 51 | 52 | Optional> ironManPowersOpt = getPowersForAlterEgo(ironMan, tonyStark); 53 | 54 | System.out.println("Iron man powers: " + ironManPowersOpt.get()); 55 | 56 | Civilian benUrich = Civilian.create("Ben Urich", new BigDecimal(15000)); 57 | 58 | Optional> benUrichPowersOpt = getPowersForAlterEgo(ironMan, benUrich); 59 | 60 | System.out.println("Iron man powers if alter ego Ben Urich: " + benUrichPowersOpt); 61 | } 62 | 63 | private Optional> getPowersForAlterEgo( 64 | Character character, Civilian alterEgo) { 65 | return match(character) 66 | .when(case2(Civilian.class, any(), any())) 67 | .get((n, w) -> Optional.>empty()) 68 | .when(case3(SuperHero.class, eq(""), any(), eq(Optional.of(alterEgo)))).get( 69 | p -> Optional.of(p)) 70 | .orElse(Optional.empty()) 71 | .getMatch(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /generator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | motif-parent 9 | com.leacox.motif 10 | 1.0-SNAPSHOT 11 | 12 | 13 | motif-generator 14 | 15 | 16 | 17 | com.google.guava 18 | guava 19 | 18.0 20 | 21 | 22 | com.leacox.motif 23 | motif 24 | 25 | 26 | com.squareup 27 | javapoet 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/Case1CasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case1; 20 | import com.leacox.motif.generate.CasesGenerator; 21 | import com.leacox.motif.generate.Match1MethodSpec; 22 | 23 | import com.squareup.javapoet.ClassName; 24 | import com.squareup.javapoet.JavaFile; 25 | import com.squareup.javapoet.ParameterizedTypeName; 26 | import com.squareup.javapoet.TypeName; 27 | import com.squareup.javapoet.TypeVariableName; 28 | 29 | import java.io.IOException; 30 | 31 | /** 32 | * Generator for {@link Case1} match cases. 33 | * 34 | * @author John Leacox 35 | */ 36 | final class Case1CasesGenerator { 37 | private Case1CasesGenerator() { 38 | } 39 | 40 | public static void main(String[] args) { 41 | TypeName A = TypeVariableName.get("A"); 42 | TypeName bounds = ParameterizedTypeName.get(ClassName.get(Case1.class), A); 43 | TypeName t = TypeVariableName.get("T", bounds); 44 | TypeName clazz = ParameterizedTypeName.get(ClassName.get(Class.class), t); 45 | 46 | Match1MethodSpec case1Match = Match1MethodSpec.builder() 47 | .withName("case1").withSummaryJavadoc("Matches a case class of one element.\n") 48 | .addNonMatchParam(clazz, "clazz").withMatchExtractor(Case1FieldExtractor.class, "clazz") 49 | .withParamA(A, "a").build(); 50 | 51 | JavaFile cases1CasesFile = CasesGenerator.newBuilder( 52 | "com.leacox.motif.cases", "Case1Cases", t) 53 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 54 | .addJavadoc("Motif cases for matching a {@link Case1}.\n") 55 | .addMatch1Method(case1Match) 56 | .build().generate(); 57 | 58 | try { 59 | cases1CasesFile.writeTo(System.out); 60 | } catch (IOException e) { 61 | e.printStackTrace(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/Case2CasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case2; 20 | import com.leacox.motif.generate.CasesGenerator; 21 | import com.leacox.motif.generate.Match2MethodSpec; 22 | 23 | import com.squareup.javapoet.ClassName; 24 | import com.squareup.javapoet.JavaFile; 25 | import com.squareup.javapoet.ParameterizedTypeName; 26 | import com.squareup.javapoet.TypeName; 27 | import com.squareup.javapoet.TypeVariableName; 28 | 29 | import java.io.IOException; 30 | 31 | /** 32 | * Generator for {@link Case2} match cases. 33 | * 34 | * @author John Leacox 35 | */ 36 | final class Case2CasesGenerator { 37 | private Case2CasesGenerator() { 38 | } 39 | 40 | public static void main(String[] args) { 41 | TypeName A = TypeVariableName.get("A"); 42 | TypeName B = TypeVariableName.get("B"); 43 | TypeName bounds = ParameterizedTypeName.get(ClassName.get(Case2.class), A, B); 44 | TypeName t = TypeVariableName.get("T", bounds); 45 | TypeName clazz = ParameterizedTypeName.get(ClassName.get(Class.class), t); 46 | 47 | Match2MethodSpec case2Match = Match2MethodSpec.builder() 48 | .withName("case2").withSummaryJavadoc("Matches a case class of two elements.\n") 49 | .addNonMatchParam(clazz, "clazz").withMatchExtractor(Case2FieldExtractor.class, "clazz") 50 | .withParamA(A, "a").withParamB(B, "b").build(); 51 | 52 | JavaFile case2CasesFile = CasesGenerator.newBuilder( 53 | "com.leacox.motif.cases", "Case2Cases", t) 54 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 55 | .addJavadoc("Motif cases for matching a {@link Case2}.\n") 56 | .addMatch2Method(case2Match) 57 | .build().generate(); 58 | 59 | try { 60 | case2CasesFile.writeTo(System.out); 61 | } catch (IOException e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/Case3CasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case3; 20 | import com.leacox.motif.generate.CasesGenerator; 21 | import com.leacox.motif.generate.Match3MethodSpec; 22 | 23 | import com.squareup.javapoet.ClassName; 24 | import com.squareup.javapoet.JavaFile; 25 | import com.squareup.javapoet.ParameterizedTypeName; 26 | import com.squareup.javapoet.TypeName; 27 | import com.squareup.javapoet.TypeVariableName; 28 | 29 | import java.io.IOException; 30 | 31 | /** 32 | * Generator for {@link Case3} match cases. 33 | * 34 | * @author John Leacox 35 | */ 36 | final class Case3CasesGenerator { 37 | private Case3CasesGenerator() { 38 | } 39 | 40 | public static void main(String[] args) { 41 | TypeName A = TypeVariableName.get("A"); 42 | TypeName B = TypeVariableName.get("B"); 43 | TypeName C = TypeVariableName.get("C"); 44 | TypeName bounds = ParameterizedTypeName.get(ClassName.get(Case3.class), A, B, C); 45 | TypeName t = TypeVariableName.get("T", bounds); 46 | TypeName clazz = ParameterizedTypeName.get(ClassName.get(Class.class), t); 47 | 48 | Match3MethodSpec case3Match = Match3MethodSpec.builder() 49 | .withName("case3").withSummaryJavadoc("Matches a case class of three elements.\n") 50 | .addNonMatchParam(clazz, "clazz").withMatchExtractor(Case3FieldExtractor.class, "clazz") 51 | .withParamA(A, "a").withParamB(B, "b").withParamC(C, "c").build(); 52 | 53 | JavaFile case3CasesFile = CasesGenerator.newBuilder( 54 | "com.leacox.motif.cases", "Case3Cases", t) 55 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 56 | .addJavadoc("Motif cases for matching a {@link Case3}.\n") 57 | .addMatch3Method(case3Match) 58 | .build().generate(); 59 | 60 | try { 61 | case3CasesFile.writeTo(System.out); 62 | } catch (IOException e) { 63 | e.printStackTrace(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/Copyright.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | /** 20 | * Utility for copyright notices on Motif internally generated classes. 21 | * 22 | * @author John Leacox 23 | */ 24 | final class Copyright { 25 | private Copyright() { 26 | } 27 | 28 | public static final String COPYRIGHT_NOTICE = 29 | "/*\n" 30 | + " * Copyright (C) 2015 John Leacox\n" 31 | + " *\n" 32 | + " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 33 | + " * you may not use this file except in compliance with the License.\n" 34 | + " * You may obtain a copy of the License at\n" 35 | + " *\n" 36 | + " * http://www.apache.org/licenses/LICENSE-2.0\n" 37 | + " *\n" 38 | + " * Unless required by applicable law or agreed to in writing, software\n" 39 | + " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 40 | + " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" 41 | + " * See the License for the specific language governing permissions and\n" 42 | + " * limitations under the License.\n" 43 | + " */\n"; 44 | } 45 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/ListConsCasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.generate.CasesGenerator; 20 | import com.leacox.motif.generate.Match0MethodSpec; 21 | import com.leacox.motif.generate.Match1MethodSpec; 22 | import com.leacox.motif.generate.Match2MethodSpec; 23 | 24 | import com.squareup.javapoet.ClassName; 25 | import com.squareup.javapoet.JavaFile; 26 | import com.squareup.javapoet.ParameterizedTypeName; 27 | import com.squareup.javapoet.TypeName; 28 | import com.squareup.javapoet.TypeVariableName; 29 | 30 | import java.io.IOException; 31 | import java.util.List; 32 | 33 | /** 34 | * Generator for {@link List} cons match cases. 35 | * @author John Leacox 36 | */ 37 | final class ListConsCasesGenerator { 38 | private ListConsCasesGenerator() { 39 | } 40 | 41 | public static void main(String[] args) { 42 | TypeName E = TypeVariableName.get("T"); 43 | TypeName l = ParameterizedTypeName.get(ClassName.get(List.class), E); 44 | 45 | Match0MethodSpec nilMatch = Match0MethodSpec.builder() 46 | .withName("nil").withSummaryJavadoc("Matches an empty list.\n") 47 | .withMatchExtractor(ListConsNilFieldExtractor.class).build(); 48 | 49 | Match1MethodSpec headNilMatch = Match1MethodSpec.builder() 50 | .withName("headNil").withSummaryJavadoc("Matches a list with exactly one element.\n") 51 | .withMatchExtractor(ListConsHeadFieldExtractor.class).withParamA(E, "head").build(); 52 | 53 | Match2MethodSpec headTailMatch = Match2MethodSpec.builder() 54 | .withName("headTail") 55 | .withSummaryJavadoc( 56 | "Matches a list with a head element and a tail of remaining elements.\n") 57 | .withMatchExtractor(ListConsHeadTailFieldExtractor.class).withParamA(E, "head") 58 | .withParamB(l, "tail").build(); 59 | 60 | JavaFile listCasesFile = CasesGenerator.newBuilder("com.leacox.motif.cases", "ListConsCases", l) 61 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 62 | .addJavadoc("Motif cases for matching a {@link List} with cons.\n") 63 | .addMatch0Method(nilMatch) 64 | .addMatch1Method(headNilMatch) 65 | .addMatch2Method(headTailMatch) 66 | .build().generate(); 67 | 68 | try { 69 | listCasesFile.writeTo(System.out); 70 | } catch (IOException e) { 71 | e.printStackTrace(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/OptionalCasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.generate.CasesGenerator; 20 | import com.leacox.motif.generate.Match0MethodSpec; 21 | import com.leacox.motif.generate.Match1MethodSpec; 22 | 23 | import com.squareup.javapoet.ClassName; 24 | import com.squareup.javapoet.JavaFile; 25 | import com.squareup.javapoet.ParameterizedTypeName; 26 | import com.squareup.javapoet.TypeName; 27 | import com.squareup.javapoet.TypeVariableName; 28 | 29 | import java.io.IOException; 30 | import java.util.Optional; 31 | 32 | /** 33 | * Generator for {@link Optional} match cases. 34 | * 35 | * @author John Leacox 36 | */ 37 | final class OptionalCasesGenerator { 38 | private OptionalCasesGenerator() { 39 | } 40 | 41 | public static void main(String[] args) { 42 | TypeName T = TypeVariableName.get("T"); 43 | TypeName o = ParameterizedTypeName.get(ClassName.get(Optional.class), T); 44 | 45 | Match0MethodSpec noneMatch = Match0MethodSpec.builder() 46 | .withName("none").withSummaryJavadoc("Matches an empty {@link Optional}.\n") 47 | .withMatchExtractor(OptionalNoneFieldExtractor.class).build(); 48 | 49 | Match1MethodSpec someMatch = Match1MethodSpec.builder() 50 | .withName("some").withSummaryJavadoc("Matches a non-empty {@link Optional}.\n") 51 | .withMatchExtractor(OptionalFieldExtractor.class).withParamA(T, "t").build(); 52 | 53 | JavaFile optionalCasesFile = 54 | CasesGenerator.newBuilder("com.leacox.motif.cases", "OptionalCases", o) 55 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 56 | .addJavadoc("Motif cases for matching an {@link Optional}.\n") 57 | .addMatch0Method(noneMatch) 58 | .addMatch1Method(someMatch) 59 | .build().generate(); 60 | 61 | try { 62 | optionalCasesFile.writeTo(System.out); 63 | } catch (IOException e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/PrimitiveCasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.generate.CasesGenerator; 20 | import com.leacox.motif.generate.Match1MethodSpec; 21 | import com.leacox.motif.tuple.Tuple1; 22 | 23 | import com.squareup.javapoet.ClassName; 24 | import com.squareup.javapoet.JavaFile; 25 | import com.squareup.javapoet.ParameterizedTypeName; 26 | import com.squareup.javapoet.TypeName; 27 | import com.squareup.javapoet.TypeVariableName; 28 | 29 | import java.io.IOException; 30 | 31 | /** 32 | * Generator for primitive match cases. 33 | * 34 | *

Note: This isn't currently used. 35 | * 36 | * @author John Leacox 37 | */ 38 | final class PrimitiveCasesGenerator { 39 | private PrimitiveCasesGenerator() { 40 | } 41 | 42 | public static void main(String[] args) { 43 | TypeName A = TypeVariableName.get("A"); 44 | TypeName t = ParameterizedTypeName.get(ClassName.get(Tuple1.class), A); 45 | 46 | Match1MethodSpec byteMatch = Match1MethodSpec.builder() 47 | .withName("aByte").withSummaryJavadoc("Matches a byte.\n") 48 | .withMatchExtractor(PrimitiveFieldExtractor.class, Byte.class) 49 | .withParamA(TypeName.get(byte.class), "b").build(); 50 | 51 | JavaFile primitiveCasesFile = CasesGenerator.newBuilder( 52 | "com.leacox.motif.cases", "PrimitiveCases", t) 53 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 54 | .addJavadoc("Motif cases for matching a primitive types.\n") 55 | .addMatch1Method(byteMatch) 56 | .build().generate(); 57 | 58 | try { 59 | primitiveCasesFile.writeTo(System.out); 60 | } catch (IOException e) { 61 | e.printStackTrace(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/Tuple1CasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.generate.CasesGenerator; 20 | import com.leacox.motif.generate.Match1MethodSpec; 21 | import com.leacox.motif.tuple.Tuple1; 22 | 23 | import com.squareup.javapoet.ClassName; 24 | import com.squareup.javapoet.JavaFile; 25 | import com.squareup.javapoet.ParameterizedTypeName; 26 | import com.squareup.javapoet.TypeName; 27 | import com.squareup.javapoet.TypeVariableName; 28 | 29 | import java.io.IOException; 30 | 31 | /** 32 | * Generator for {@link Tuple1} match cases. 33 | * 34 | * @author John Leacox 35 | */ 36 | final class Tuple1CasesGenerator { 37 | private Tuple1CasesGenerator() { 38 | } 39 | 40 | public static void main(String[] args) { 41 | TypeName A = TypeVariableName.get("A"); 42 | TypeName t = ParameterizedTypeName.get(ClassName.get(Tuple1.class), A); 43 | 44 | Match1MethodSpec tuple1Match = Match1MethodSpec.builder() 45 | .withName("tuple1").withSummaryJavadoc("Matches a tuple of 1 element.\n") 46 | .withMatchExtractor(Tuple1FieldExtractor.class).withParamA(A, "a").build(); 47 | 48 | JavaFile tuple1CasesFile = CasesGenerator.newBuilder( 49 | "com.leacox.motif.cases", "Tuple1Cases", t) 50 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 51 | .addJavadoc("Motif cases for matching a {@link Tuple1}.\n") 52 | .addMatch1Method(tuple1Match) 53 | .build().generate(); 54 | 55 | try { 56 | tuple1CasesFile.writeTo(System.out); 57 | } catch (IOException e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/Tuple2CasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.generate.CasesGenerator; 20 | import com.leacox.motif.generate.Match2MethodSpec; 21 | import com.leacox.motif.tuple.Tuple2; 22 | 23 | import com.squareup.javapoet.ClassName; 24 | import com.squareup.javapoet.JavaFile; 25 | import com.squareup.javapoet.ParameterizedTypeName; 26 | import com.squareup.javapoet.TypeName; 27 | import com.squareup.javapoet.TypeVariableName; 28 | 29 | import java.io.IOException; 30 | 31 | /** 32 | * Generator for {@link Tuple2} match cases. 33 | * 34 | * @author John Leacox 35 | */ 36 | final class Tuple2CasesGenerator { 37 | private Tuple2CasesGenerator() { 38 | } 39 | 40 | public static void main(String[] args) { 41 | TypeName A = TypeVariableName.get("A"); 42 | TypeName B = TypeVariableName.get("B"); 43 | TypeName t = ParameterizedTypeName.get(ClassName.get(Tuple2.class), A, B); 44 | 45 | Match2MethodSpec tuple2Match = Match2MethodSpec.builder() 46 | .withName("tuple2").withSummaryJavadoc("Matches a tuple of 2 elements.\n") 47 | .withMatchExtractor(Tuple2FieldExtractor.class).withParamA(A, "a").withParamB(B, "b") 48 | .build(); 49 | 50 | JavaFile tuple2CasesFile = CasesGenerator.newBuilder( 51 | "com.leacox.motif.cases", "Tuple2Cases", t) 52 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 53 | .addJavadoc("Motif cases for matching a {@link Tuple2}.\n") 54 | .addMatch2Method(tuple2Match) 55 | .build().generate(); 56 | 57 | try { 58 | tuple2CasesFile.writeTo(System.out); 59 | } catch (IOException e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/cases/Tuple3CasesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.generate.CasesGenerator; 20 | import com.leacox.motif.generate.Match3MethodSpec; 21 | import com.leacox.motif.tuple.Tuple3; 22 | 23 | import com.squareup.javapoet.ClassName; 24 | import com.squareup.javapoet.JavaFile; 25 | import com.squareup.javapoet.ParameterizedTypeName; 26 | import com.squareup.javapoet.TypeName; 27 | import com.squareup.javapoet.TypeVariableName; 28 | 29 | import java.io.IOException; 30 | 31 | /** 32 | * Generator for {@link Tuple3} match cases. 33 | * 34 | * @author John Leacox 35 | */ 36 | final class Tuple3CasesGenerator { 37 | private Tuple3CasesGenerator() { 38 | } 39 | 40 | public static void main(String[] args) { 41 | TypeName A = TypeVariableName.get("A"); 42 | TypeName B = TypeVariableName.get("B"); 43 | TypeName C = TypeVariableName.get("C"); 44 | TypeName t = ParameterizedTypeName.get(ClassName.get(Tuple3.class), A, B, C); 45 | 46 | Match3MethodSpec tuple3Match = Match3MethodSpec.builder() 47 | .withName("tuple3").withSummaryJavadoc("Matches a tuple of 2 elements.\n") 48 | .withMatchExtractor(Tuple3FieldExtractor.class).withParamA(A, "a") 49 | .withParamB(B, "b").withParamC(C, "c").build(); 50 | 51 | JavaFile tuple3CasesFile = CasesGenerator.newBuilder( 52 | "com.leacox.motif.cases", "Tuple3Cases", t) 53 | .addFileComment(Copyright.COPYRIGHT_NOTICE) 54 | .addJavadoc("Motif cases for matching a {@link Tuple3}.\n") 55 | .addMatch3Method(tuple3Match) 56 | .build().generate(); 57 | 58 | try { 59 | tuple3CasesFile.writeTo(System.out); 60 | } catch (IOException e) { 61 | e.printStackTrace(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/generate/Match0MethodSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.generate; 18 | 19 | import static com.google.common.base.Preconditions.checkNotNull; 20 | 21 | import com.leacox.motif.extract.FieldExtractor; 22 | import com.leacox.motif.tuple.Tuple2; 23 | 24 | import com.google.common.collect.Lists; 25 | import com.squareup.javapoet.TypeName; 26 | 27 | import java.util.List; 28 | 29 | /** 30 | * Specification of a match method with 0-arity. 31 | * 32 | * @author John Leacox 33 | */ 34 | public final class Match0MethodSpec { 35 | final String name; 36 | final List nonMatchParams; 37 | final Tuple2, Object[]> fieldExtractorWithArgs; 38 | final String summaryJavadoc; 39 | 40 | private Match0MethodSpec(Builder builder) { 41 | this.name = builder.name; 42 | this.nonMatchParams = builder.nonMatchParams; 43 | this.fieldExtractorWithArgs = builder.fieldExtractorWithArgs; 44 | this.summaryJavadoc = builder.summaryJavadoc; 45 | } 46 | 47 | public static Builder builder() { 48 | return new Builder(); 49 | } 50 | 51 | public static class Builder { 52 | private String name; 53 | private final List nonMatchParams = Lists.newArrayList(); 54 | private Tuple2, Object[]> fieldExtractorWithArgs; 55 | private String summaryJavadoc; 56 | 57 | public Builder withName(String methodName) { 58 | this.name = methodName; 59 | return this; 60 | } 61 | 62 | public Builder addNonMatchParam(TypeName type, String name) { 63 | nonMatchParams.add(MethodParam.create(type, name)); 64 | return this; 65 | } 66 | 67 | public Builder withMatchExtractor( 68 | Class matchExtractor, Object... args) { 69 | fieldExtractorWithArgs = Tuple2.of(matchExtractor, args); 70 | return this; 71 | } 72 | 73 | public Builder withSummaryJavadoc(String summaryJavadoc) { 74 | this.summaryJavadoc = summaryJavadoc; 75 | return this; 76 | } 77 | 78 | /** 79 | * Creates a new instances of {@link Match0MethodSpec} with the builder parameters. 80 | */ 81 | public Match0MethodSpec build() { 82 | checkNotNull(name, "name == null"); 83 | checkNotNull(fieldExtractorWithArgs, "matchExtractor == null"); 84 | 85 | return new Match0MethodSpec(this); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/generate/Match1MethodSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.generate; 18 | 19 | import static com.google.common.base.Preconditions.checkNotNull; 20 | 21 | import com.leacox.motif.extract.FieldExtractor; 22 | import com.leacox.motif.tuple.Tuple2; 23 | 24 | import com.google.common.collect.Lists; 25 | import com.squareup.javapoet.TypeName; 26 | 27 | import java.util.List; 28 | 29 | /** 30 | * Specification of a match method that with 1-arity. 31 | * 32 | * @author John Leacox 33 | */ 34 | 35 | public final class Match1MethodSpec { 36 | final String name; 37 | final List nonMatchParams; 38 | final Tuple2, Object[]> fieldExtractorWithArgs; 39 | final String summaryJavadoc; 40 | final MethodParam paramA; 41 | 42 | private Match1MethodSpec(Builder builder) { 43 | this.name = builder.name; 44 | this.nonMatchParams = builder.nonMatchParams; 45 | this.fieldExtractorWithArgs = builder.fieldExtractorWithArgs; 46 | this.summaryJavadoc = builder.summaryJavadoc; 47 | this.paramA = builder.paramA; 48 | } 49 | 50 | public static Builder builder() { 51 | return new Builder(); 52 | } 53 | 54 | public static class Builder { 55 | private String name; 56 | private final List nonMatchParams = Lists.newArrayList(); 57 | private Tuple2, Object[]> fieldExtractorWithArgs; 58 | private String summaryJavadoc; 59 | private MethodParam paramA; 60 | 61 | public Builder withName(String methodName) { 62 | this.name = methodName; 63 | return this; 64 | } 65 | 66 | public Builder addNonMatchParam(TypeName type, String name) { 67 | nonMatchParams.add(MethodParam.create(type, name)); 68 | return this; 69 | } 70 | 71 | public Builder withMatchExtractor( 72 | Class matchExtractor, Object... args) { 73 | fieldExtractorWithArgs = Tuple2.of(matchExtractor, args); 74 | return this; 75 | } 76 | 77 | public Builder withSummaryJavadoc(String summaryJavadoc) { 78 | this.summaryJavadoc = summaryJavadoc; 79 | return this; 80 | } 81 | 82 | public Builder withParamA(TypeName type, String name) { 83 | this.paramA = MethodParam.create(type, name); 84 | return this; 85 | } 86 | 87 | /** 88 | * Creates a new instances of {@link Match1MethodSpec} with the builder parameters. 89 | */ 90 | public Match1MethodSpec build() { 91 | checkNotNull(name, "name == null"); 92 | checkNotNull(fieldExtractorWithArgs, "matchExtractor == null"); 93 | checkNotNull(paramA, "paramA == null"); 94 | 95 | return new Match1MethodSpec(this); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/generate/Match2MethodSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.generate; 18 | 19 | import static com.google.common.base.Preconditions.checkNotNull; 20 | 21 | import com.leacox.motif.extract.FieldExtractor; 22 | import com.leacox.motif.tuple.Tuple2; 23 | 24 | import com.google.common.collect.Lists; 25 | import com.squareup.javapoet.TypeName; 26 | 27 | import java.util.List; 28 | 29 | /** 30 | * Specification of a match method with 2-arity. 31 | * 32 | * @author John Leacox 33 | */ 34 | public final class Match2MethodSpec { 35 | final String name; 36 | final List nonMatchParams; 37 | final Tuple2, Object[]> fieldExtractorWithArgs; 38 | final String summaryJavadoc; 39 | final MethodParam paramA; 40 | final MethodParam paramB; 41 | 42 | private Match2MethodSpec(Builder builder) { 43 | this.name = builder.name; 44 | this.nonMatchParams = builder.nonMatchParams; 45 | this.fieldExtractorWithArgs = builder.fieldExtractorWithArgs; 46 | this.summaryJavadoc = builder.summaryJavadoc; 47 | this.paramA = builder.paramA; 48 | this.paramB = builder.paramB; 49 | } 50 | 51 | public static Builder builder() { 52 | return new Builder(); 53 | } 54 | 55 | public static class Builder { 56 | private String name; 57 | private final List nonMatchParams = Lists.newArrayList(); 58 | private Tuple2, Object[]> fieldExtractorWithArgs; 59 | private String summaryJavadoc; 60 | private MethodParam paramA; 61 | private MethodParam paramB; 62 | 63 | public Builder withName(String methodName) { 64 | this.name = methodName; 65 | return this; 66 | } 67 | 68 | public Builder addNonMatchParam(TypeName type, String name) { 69 | nonMatchParams.add(MethodParam.create(type, name)); 70 | return this; 71 | } 72 | 73 | public Builder withMatchExtractor( 74 | Class matchExtractor, Object... args) { 75 | fieldExtractorWithArgs = Tuple2.of(matchExtractor, args); 76 | return this; 77 | } 78 | 79 | public Builder withSummaryJavadoc(String summaryJavadoc) { 80 | this.summaryJavadoc = summaryJavadoc; 81 | return this; 82 | } 83 | 84 | public Builder withParamA(TypeName type, String name) { 85 | this.paramA = MethodParam.create(type, name); 86 | return this; 87 | } 88 | 89 | public Builder withParamB(TypeName type, String name) { 90 | this.paramB = MethodParam.create(type, name); 91 | return this; 92 | } 93 | 94 | /** 95 | * Creates a new instances of {@link Match2MethodSpec} with the builder parameters. 96 | */ 97 | public Match2MethodSpec build() { 98 | checkNotNull(name, "name == null"); 99 | checkNotNull(fieldExtractorWithArgs, "matchExtractor == null"); 100 | checkNotNull(paramA, "paramA == null"); 101 | checkNotNull(paramB, "paramB == null"); 102 | 103 | return new Match2MethodSpec(this); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/generate/Match3MethodSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.generate; 18 | 19 | import static com.google.common.base.Preconditions.checkNotNull; 20 | 21 | import com.leacox.motif.extract.FieldExtractor; 22 | import com.leacox.motif.tuple.Tuple2; 23 | 24 | import com.google.common.collect.Lists; 25 | import com.squareup.javapoet.TypeName; 26 | 27 | import java.util.List; 28 | 29 | /** 30 | * Specification of a match method with 3-arity. 31 | * 32 | * @author John Leacox 33 | */ 34 | public final class Match3MethodSpec { 35 | final String name; 36 | final List nonMatchParams; 37 | final Tuple2, Object[]> fieldExtractorWithArgs; 38 | final String summaryJavadoc; 39 | final MethodParam paramA; 40 | final MethodParam paramB; 41 | final MethodParam paramC; 42 | 43 | private Match3MethodSpec(Builder builder) { 44 | this.name = builder.name; 45 | this.nonMatchParams = builder.nonMatchParams; 46 | this.fieldExtractorWithArgs = builder.fieldExtractorWithArgs; 47 | this.summaryJavadoc = builder.summaryJavadoc; 48 | this.paramA = builder.paramA; 49 | this.paramB = builder.paramB; 50 | this.paramC = builder.paramC; 51 | } 52 | 53 | public static Builder builder() { 54 | return new Builder(); 55 | } 56 | 57 | public static class Builder { 58 | private String name; 59 | private final List nonMatchParams = Lists.newArrayList(); 60 | private Tuple2, Object[]> fieldExtractorWithArgs; 61 | private String summaryJavadoc; 62 | private MethodParam paramA; 63 | private MethodParam paramB; 64 | private MethodParam paramC; 65 | 66 | public Builder withName(String methodName) { 67 | this.name = methodName; 68 | return this; 69 | } 70 | 71 | public Builder addNonMatchParam(TypeName type, String name) { 72 | nonMatchParams.add(MethodParam.create(type, name)); 73 | return this; 74 | } 75 | 76 | public Builder withMatchExtractor( 77 | Class matchExtractor, Object... args) { 78 | fieldExtractorWithArgs = Tuple2.of(matchExtractor, args); 79 | return this; 80 | } 81 | 82 | public Builder withSummaryJavadoc(String summaryJavadoc) { 83 | this.summaryJavadoc = summaryJavadoc; 84 | return this; 85 | } 86 | 87 | public Builder withParamA(TypeName type, String name) { 88 | this.paramA = MethodParam.create(type, name); 89 | return this; 90 | } 91 | 92 | public Builder withParamB(TypeName type, String name) { 93 | this.paramB = MethodParam.create(type, name); 94 | return this; 95 | } 96 | 97 | public Builder withParamC(TypeName type, String name) { 98 | this.paramC = MethodParam.create(type, name); 99 | return this; 100 | } 101 | 102 | /** 103 | * Creates a new instances of {@link Match3MethodSpec} with the builder parameters. 104 | */ 105 | public Match3MethodSpec build() { 106 | checkNotNull(name, "name == null"); 107 | checkNotNull(fieldExtractorWithArgs, "matchExtractor == null"); 108 | checkNotNull(paramA, "paramA == null"); 109 | checkNotNull(paramB, "paramB == null"); 110 | checkNotNull(paramC, "paramC == null"); 111 | 112 | return new Match3MethodSpec(this); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/generate/MatchType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.generate; 18 | 19 | /** 20 | * Motif matching types. 21 | * 22 | * @author John Leacox 23 | */ 24 | enum MatchType { 25 | EXACT, ANY, DECOMPOSE 26 | } 27 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/generate/MethodParam.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.generate; 18 | 19 | import com.squareup.javapoet.TypeName; 20 | 21 | /** 22 | * A parameter for a method, containing both the type and the name of the parameter. 23 | * 24 | * @author John Leacox 25 | */ 26 | final class MethodParam { 27 | public TypeName type; 28 | public String name; 29 | 30 | private MethodParam(TypeName type, String name) { 31 | this.type = type; 32 | this.name = name; 33 | } 34 | 35 | public static MethodParam create(TypeName type, String name) { 36 | return new MethodParam(type, name); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /generator/src/main/java/com/leacox/motif/generate/TypeNameWithArity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.generate; 18 | 19 | import com.squareup.javapoet.TypeName; 20 | 21 | /** 22 | * A pair containing a type and its arity. 23 | * 24 | * @author John Leacox 25 | */ 26 | final class TypeNameWithArity { 27 | public final TypeName typeName; 28 | public final int arity; 29 | 30 | private TypeNameWithArity(TypeName typeName, int arity) { 31 | this.typeName = typeName; 32 | this.arity = arity; 33 | } 34 | 35 | public static TypeNameWithArity of(TypeName typeName, int arity) { 36 | return new TypeNameWithArity(typeName, arity); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /hamcrest/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | motif-parent 9 | com.leacox.motif 10 | 1.0-SNAPSHOT 11 | 12 | 13 | motif-hamcrest 14 | Motif Hamcrest matching extensions 15 | 16 | 17 | 18 | com.leacox.motif 19 | motif 20 | 21 | 22 | org.hamcrest 23 | hamcrest-core 24 | 1.3 25 | 26 | 27 | 28 | 29 | com.insightfullogic 30 | lambda-behave 31 | 0.3 32 | test 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /hamcrest/src/main/java/com/leacox/motif/hamcrest/CaseThatCases.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.hamcrest; 18 | 19 | import static org.hamcrest.CoreMatchers.equalTo; 20 | 21 | import com.leacox.motif.extract.DecomposableMatchBuilder1; 22 | import com.leacox.motif.extract.Extractor1; 23 | import com.leacox.motif.extract.FieldExtractor; 24 | import com.leacox.motif.extract.matchers.Matcher; 25 | import com.leacox.motif.extract.util.Lists; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | import java.util.Optional; 30 | 31 | /** 32 | * Motif cases for matching a hamcrest {@link Matcher}. 33 | * 34 | * @author John Leacox 35 | */ 36 | public class CaseThatCases { 37 | private static class IdentityExtractor implements Extractor1 { 38 | @Override 39 | public Optional unapply(T t) { 40 | return Optional.ofNullable(t); 41 | } 42 | 43 | @Override 44 | public Class getExtractorClass() { 45 | return Object.class; 46 | } 47 | } 48 | 49 | private static class IdentityFieldExtractor implements FieldExtractor { 50 | private final IdentityExtractor identityExtractor = new IdentityExtractor<>(); 51 | 52 | @Override 53 | public Optional> unapply(T value) { 54 | Optional opt = identityExtractor.unapply(value); 55 | if (!opt.isPresent()) { 56 | return Optional.empty(); 57 | } 58 | 59 | List fields = new ArrayList<>(); 60 | fields.add(opt.get()); 61 | 62 | return Optional.of(fields); 63 | } 64 | 65 | @Override 66 | public Class getExtractorClass() { 67 | return identityExtractor.getExtractorClass(); 68 | } 69 | } 70 | 71 | private static class HamcrestMatcher implements Matcher { 72 | private final org.hamcrest.Matcher matcher; 73 | 74 | private HamcrestMatcher(org.hamcrest.Matcher matcher) { 75 | this.matcher = matcher; 76 | } 77 | 78 | static HamcrestMatcher of(org.hamcrest.Matcher matcher) { 79 | return new HamcrestMatcher<>(matcher); 80 | } 81 | 82 | @Override 83 | public boolean matches(Object arg) { 84 | return matcher.matches(arg); 85 | } 86 | } 87 | 88 | /** 89 | * Matches on a hamcrest {@link org.hamcrest.Matcher}. 90 | * 91 | *

If the hamcrest matcher returns a match, then motif will consider it a match. 92 | * 93 | *

If matched, the {@code t} value is extracted. 94 | */ 95 | public static DecomposableMatchBuilder1 caseThat(org.hamcrest.Matcher matcher) { 96 | @SuppressWarnings("unchecked") 97 | List> matchers = Lists.of((Matcher) HamcrestMatcher.of(matcher)); 98 | 99 | return new DecomposableMatchBuilder1<>(matchers, 0, new IdentityFieldExtractor<>()); 100 | } 101 | 102 | public static DecomposableMatchBuilder1 caseEq(T o) { 103 | return caseThat(equalTo(o)); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /hamcrest/src/test/java/com/leacox/motif/hamcrest/CaseThatCasesSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.hamcrest; 18 | 19 | import static com.insightfullogic.lambdabehave.Suite.describe; 20 | import static com.leacox.motif.Motif.match; 21 | import static com.leacox.motif.hamcrest.CaseThatCases.caseEq; 22 | 23 | import com.insightfullogic.lambdabehave.JunitSuiteRunner; 24 | 25 | import org.junit.runner.RunWith; 26 | 27 | /** 28 | * @author John Leacox 29 | */ 30 | @RunWith(JunitSuiteRunner.class) 31 | public class CaseThatCasesSpec { 32 | { 33 | Object pi = Math.PI; 34 | 35 | describe( 36 | "the caseThat pattern", it -> { 37 | it.should( 38 | "match pi", expect -> { 39 | String result = match(pi) 40 | .when(caseEq(42)).get(t -> "a magic no.") 41 | .when(caseEq("Hello!")).get(t -> "a greet") 42 | .when(caseEq(Math.PI)).get(t -> "another magic no.") 43 | .orElse("something else") 44 | .getMatch(); 45 | 46 | expect.that(result).is("another magic no."); 47 | } 48 | ); 49 | } 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /motif/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | com.leacox.motif 9 | motif-parent 10 | 1.0-SNAPSHOT 11 | 12 | 13 | motif 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | com.google.auto.value 26 | auto-value 27 | 28 | 29 | com.insightfullogic 30 | lambda-behave 31 | 0.3 32 | test 33 | 34 | 35 | org.assertj 36 | assertj-core 37 | 38 | 3.1.0 39 | test 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/MatchException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif; 18 | 19 | /** 20 | * An exception that indicates that a match could not be found while executing the pattern matching 21 | * cases. 22 | * 23 | *

If this exception is thrown it means the matching cases weren't exhaustive. There may be a 24 | * case that needs to be added to the pattern matching that failed. 25 | * 26 | * @author John Leacox 27 | */ 28 | public class MatchException extends RuntimeException { 29 | /** 30 | * Creates a new instance of {@link MatchException}. 31 | */ 32 | public MatchException(String message) { 33 | super(message); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/MatchesAny.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif; 18 | 19 | /** 20 | * A matcher for wildcard matching. 21 | * 22 | * @author John Leacox 23 | */ 24 | public class MatchesAny { 25 | private MatchesAny() { 26 | } 27 | 28 | private static MatchesAny ANY = new MatchesAny(); 29 | 30 | /** 31 | * Returns an instance of {@link MatchesAny}. 32 | */ 33 | public static MatchesAny any() { 34 | return ANY; 35 | } 36 | 37 | /** 38 | * Returns an instance of {@link MatchesAny} for the specified type. 39 | */ 40 | public static MatchesAny any(Class clazz) { 41 | return ANY; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/MatchesExact.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif; 18 | 19 | /** 20 | * A wrapper for exact matching. 21 | * 22 | * @author John Leacox 23 | */ 24 | public class MatchesExact { 25 | public final T t; 26 | 27 | private MatchesExact(T t) { 28 | this.t = t; 29 | } 30 | 31 | /** 32 | * Creates a new instance of {@link MatchesExact} for the specified value. 33 | */ 34 | public static MatchesExact eq(T t) { 35 | return new MatchesExact<>(t); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/caseclass/Case1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.caseclass; 18 | 19 | import com.leacox.motif.tuple.Tuple1; 20 | 21 | /** 22 | * Interface for a case class of 1 element. 23 | * 24 | *

Case classes must be able to extract their elements into a {@code Tuple}. 25 | * 26 | * @author John Leacox 27 | */ 28 | public interface Case1 { 29 | /** 30 | * Extracts the case class fields into a {@link Tuple1}. 31 | */ 32 | Tuple1 extract(); 33 | } 34 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/caseclass/Case2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.caseclass; 18 | 19 | import com.leacox.motif.tuple.Tuple2; 20 | 21 | /** 22 | * Interface for a case class of 2 elements. 23 | * 24 | *

Case classes must be able to extract their elements into a {@code Tuple}. 25 | * 26 | * @author John Leacox 27 | */ 28 | public interface Case2 { 29 | /** 30 | * Extracts the case class fields into a {@link Tuple2}. 31 | */ 32 | Tuple2 extract(); 33 | } 34 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/caseclass/Case3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.caseclass; 18 | 19 | import com.leacox.motif.tuple.Tuple3; 20 | 21 | /** 22 | * Interface for a case class of 3 elements. 23 | * 24 | *

Case classes must be able to extract their elements into a {@code Tuple}. 25 | * 26 | * @author John Leacox 27 | */ 28 | public interface Case3 { 29 | /** 30 | * Extracts the case class fields into a {@link Tuple3}. 31 | */ 32 | Tuple3 extract(); 33 | } 34 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Case1Extractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case1; 20 | import com.leacox.motif.extract.Extractor1; 21 | 22 | import java.util.Optional; 23 | 24 | /** 25 | * An extract for extracting the fields of a {@link Case1}. 26 | * 27 | * @author John Leacox 28 | */ 29 | public class Case1Extractor, A> implements Extractor1 { 30 | private final Class caseClazz; 31 | 32 | private Case1Extractor(Class caseClazz) { 33 | this.caseClazz = caseClazz; 34 | } 35 | 36 | /** 37 | * Creates a new instances of {@link Case1Extractor} for the specified {@link Case1} class. 38 | */ 39 | public static , A> Case1Extractor create(Class caseClazz) { 40 | return new Case1Extractor<>(caseClazz); 41 | } 42 | 43 | @Override 44 | public Optional unapply(T t) { 45 | return caseClazz.isAssignableFrom(t.getClass()) ? Optional.of(t.extract().first()) 46 | : Optional.empty(); 47 | } 48 | 49 | @Override 50 | public Class getExtractorClass() { 51 | return caseClazz; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Case1FieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case1; 20 | import com.leacox.motif.extract.FieldExtractor; 21 | 22 | import java.util.Collections; 23 | import java.util.List; 24 | import java.util.Optional; 25 | 26 | /** 27 | * Field extractor for {@link Case1}. 28 | * 29 | * @author John Leacox 30 | */ 31 | final class Case1FieldExtractor, A> 32 | implements FieldExtractor { 33 | private final Case1Extractor case1Extractor; 34 | 35 | Case1FieldExtractor(Class caseClazz) { 36 | this.case1Extractor = Case1Extractor.create(caseClazz); 37 | } 38 | 39 | @Override 40 | public Optional> unapply(T value) { 41 | Optional opt = case1Extractor.unapply(value); 42 | if (!opt.isPresent()) { 43 | return Optional.empty(); 44 | } 45 | 46 | return Optional.of(Collections.singletonList(opt.get())); 47 | } 48 | 49 | @Override 50 | public Class getExtractorClass() { 51 | return case1Extractor.getExtractorClass(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Case2Extractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case2; 20 | import com.leacox.motif.extract.Extractor2; 21 | import com.leacox.motif.tuple.Tuple2; 22 | 23 | import java.util.Optional; 24 | 25 | /** 26 | * An extract for extracting the fields of a {@link Case2}. 27 | * 28 | * @author John Leacox 29 | */ 30 | public class Case2Extractor, A, B> implements Extractor2 { 31 | private final Class caseClazz; 32 | 33 | Case2Extractor(Class caseClazz) { 34 | this.caseClazz = caseClazz; 35 | } 36 | 37 | /** 38 | * Creates a new instances of {@link Case2Extractor} for the specified {@link Case2} class. 39 | */ 40 | public static , A, B> Case2Extractor create(Class caseClazz) { 41 | return new Case2Extractor<>(caseClazz); 42 | } 43 | 44 | @Override 45 | public Optional> unapply(T t) { 46 | return caseClazz.isAssignableFrom(t.getClass()) ? Optional.of(t.extract()) : Optional.empty(); 47 | } 48 | 49 | @Override 50 | public Class getExtractorClass() { 51 | return caseClazz; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Case2FieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case2; 20 | import com.leacox.motif.extract.FieldExtractor; 21 | import com.leacox.motif.tuple.Tuple2; 22 | 23 | import java.util.List; 24 | import java.util.Optional; 25 | 26 | /** 27 | * Field extractor for {@link Case2}. 28 | * 29 | * @author John Leacox 30 | */ 31 | final class Case2FieldExtractor, A, B> 32 | implements FieldExtractor { 33 | private final Case2Extractor case2Extractor; 34 | 35 | Case2FieldExtractor(Class caseClazz) { 36 | this.case2Extractor = Case2Extractor.create(caseClazz); 37 | } 38 | 39 | @Override 40 | public Optional> unapply(T value) { 41 | Optional> opt = case2Extractor.unapply(value); 42 | if (!opt.isPresent()) { 43 | return Optional.empty(); 44 | } 45 | 46 | return Optional.of(opt.get().toList()); 47 | } 48 | 49 | @Override 50 | public Class getExtractorClass() { 51 | return case2Extractor.getExtractorClass(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Case3Extractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case3; 20 | import com.leacox.motif.extract.Extractor3; 21 | import com.leacox.motif.tuple.Tuple3; 22 | 23 | import java.util.Optional; 24 | 25 | /** 26 | * An extract for extracting the fields of a {@link Case3}. 27 | * 28 | * @author John Leacox 29 | */ 30 | public class Case3Extractor, A, B, C> 31 | implements Extractor3 { 32 | private final Class caseClazz; 33 | 34 | private Case3Extractor(Class caseClazz) { 35 | this.caseClazz = caseClazz; 36 | } 37 | 38 | /** 39 | * Creates a new instances of {@link Case3Extractor} for the specified {@link Case3} class. 40 | */ 41 | public static , A, B, C> Case3Extractor create( 42 | Class caseClazz) { 43 | return new Case3Extractor<>(caseClazz); 44 | } 45 | 46 | @Override 47 | public Optional> unapply(T t) { 48 | if (!caseClazz.isAssignableFrom(t.getClass())) { 49 | return Optional.empty(); 50 | } 51 | 52 | return Optional.of(t.extract()); 53 | } 54 | 55 | @Override 56 | public Class getExtractorClass() { 57 | return caseClazz; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Case3FieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case3; 20 | import com.leacox.motif.extract.FieldExtractor; 21 | import com.leacox.motif.tuple.Tuple3; 22 | 23 | import java.util.List; 24 | import java.util.Optional; 25 | 26 | /** 27 | * Field extractor for {@link Case3}. 28 | * 29 | * @author John Leacox 30 | */ 31 | final class Case3FieldExtractor, A, B, C> 32 | implements FieldExtractor { 33 | private final Case3Extractor case3Extractor; 34 | 35 | Case3FieldExtractor(Class caseClazz) { 36 | this.case3Extractor = Case3Extractor.create(caseClazz); 37 | } 38 | 39 | @Override 40 | public Optional> unapply(T value) { 41 | Optional> opt = case3Extractor.unapply(value); 42 | if (!opt.isPresent()) { 43 | return Optional.empty(); 44 | } 45 | 46 | return Optional.of(opt.get().toList()); 47 | } 48 | 49 | @Override 50 | public Class getExtractorClass() { 51 | return case3Extractor.getExtractorClass(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/ListConsHeadExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor1; 20 | 21 | import java.util.List; 22 | import java.util.Optional; 23 | 24 | /** 25 | * An extractor for extracting a {@link List} with a single element. 26 | * 27 | * @author John Leacox 28 | */ 29 | public class ListConsHeadExtractor implements Extractor1, A> { 30 | private ListConsHeadExtractor() { 31 | } 32 | 33 | /** 34 | * Creates a new instance of {@link ListConsHeadExtractor}. 35 | */ 36 | public static ListConsHeadExtractor create() { 37 | return new ListConsHeadExtractor<>(); 38 | } 39 | 40 | @Override 41 | public Optional unapply(List list) { 42 | if (list.size() == 1) { 43 | return Optional.of(list.get(0)); 44 | } 45 | 46 | return Optional.empty(); 47 | } 48 | 49 | @Override 50 | public Class getExtractorClass() { 51 | return List.class; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/ListConsHeadFieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * Field extractor for extracting a {@link List} with a single element. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class ListConsHeadFieldExtractor implements FieldExtractor> { 31 | private final ListConsHeadExtractor headExtractor = ListConsHeadExtractor.create(); 32 | 33 | @Override 34 | public Optional> unapply(List value) { 35 | Optional opt = headExtractor.unapply(value); 36 | if (!opt.isPresent()) { 37 | return Optional.empty(); 38 | } 39 | 40 | List fields = new ArrayList<>(); 41 | fields.add(opt.get()); 42 | 43 | return Optional.of(fields); 44 | } 45 | 46 | @Override 47 | public Class getExtractorClass() { 48 | return headExtractor.getExtractorClass(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/ListConsHeadTailExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor2; 20 | import com.leacox.motif.tuple.Tuple2; 21 | 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * An extractor for extracting a {@link List} into a head element and a tail of remaining 27 | * elements. 28 | * 29 | * @author John Leacox 30 | */ 31 | public class ListConsHeadTailExtractor implements Extractor2, A, List> { 32 | private ListConsHeadTailExtractor() { 33 | } 34 | 35 | /** 36 | * Creates a new instance of {@link ListConsHeadTailExtractor}. 37 | */ 38 | public static ListConsHeadTailExtractor create() { 39 | return new ListConsHeadTailExtractor<>(); 40 | } 41 | 42 | @Override 43 | public Optional>> unapply(List list) { 44 | if (list.isEmpty()) { 45 | return Optional.empty(); 46 | } 47 | 48 | return Optional.of(Tuple2.of(list.get(0), list.subList(1, list.size()))); 49 | } 50 | 51 | @Override 52 | public Class getExtractorClass() { 53 | return List.class; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/ListConsHeadTailFieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | import com.leacox.motif.tuple.Tuple2; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | import java.util.Optional; 25 | 26 | /** 27 | * Field extractor for extracting a {@link List} into a head element and a tail of remaining 28 | * elements. 29 | * 30 | * @author John Leacox 31 | */ 32 | final class ListConsHeadTailFieldExtractor implements FieldExtractor> { 33 | private final ListConsHeadTailExtractor listExtractor = ListConsHeadTailExtractor.create(); 34 | 35 | @Override 36 | public Optional> unapply(List value) { 37 | Optional>> opt = listExtractor.unapply(value); 38 | if (!opt.isPresent()) { 39 | return Optional.empty(); 40 | } 41 | 42 | List fields = new ArrayList<>(); 43 | fields.add(opt.get().first()); 44 | fields.add(opt.get().second()); 45 | 46 | return Optional.of(fields); 47 | } 48 | 49 | @Override 50 | public Class getExtractorClass() { 51 | return listExtractor.getExtractorClass(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/ListConsNilExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor0; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * An extractor for extracting an empty list. 25 | * 26 | * @author John Leacox 27 | */ 28 | public class ListConsNilExtractor implements Extractor0> { 29 | private ListConsNilExtractor() { 30 | } 31 | 32 | /** 33 | * Creates a new instance of {@link ListConsNilExtractor}. 34 | */ 35 | public static ListConsNilExtractor create() { 36 | return new ListConsNilExtractor<>(); 37 | } 38 | 39 | @Override 40 | public boolean unapply(List list) { 41 | return list.isEmpty(); 42 | } 43 | 44 | @Override 45 | public Class getExtractorClass() { 46 | return List.class; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/ListConsNilFieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | 21 | import java.util.Collections; 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * Field extractor for extracting an empty list. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class ListConsNilFieldExtractor implements FieldExtractor> { 31 | private final ListConsNilExtractor emptyListExtractor = ListConsNilExtractor.create(); 32 | 33 | @Override 34 | public Optional> unapply(List value) { 35 | if (!emptyListExtractor.unapply(value)) { 36 | return Optional.empty(); 37 | } 38 | 39 | return Optional.of(Collections.emptyList()); 40 | } 41 | 42 | @Override 43 | public Class getExtractorClass() { 44 | return emptyListExtractor.getExtractorClass(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/OptionalExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor1; 20 | 21 | import java.util.Optional; 22 | 23 | /** 24 | * An extractor for extracting an {@link Optional}. 25 | * 26 | * @author John Leacox 27 | */ 28 | public class OptionalExtractor implements Extractor1, T> { 29 | private OptionalExtractor() { 30 | } 31 | 32 | /** 33 | * Creates a new instance of {@link OptionalExtractor}. 34 | */ 35 | public static OptionalExtractor create() { 36 | return new OptionalExtractor<>(); 37 | } 38 | 39 | @Override 40 | public Optional unapply(Optional t) { 41 | if (t.isPresent()) { 42 | return t; 43 | } else { 44 | return Optional.empty(); 45 | } 46 | } 47 | 48 | @Override 49 | public Class getExtractorClass() { 50 | return Optional.class; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/OptionalFieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * A field extractor for extracting the value in a non-empty {@link Optional}. 27 | * 28 | * @author John Leacox 29 | */ 30 | public class OptionalFieldExtractor implements FieldExtractor> { 31 | private final OptionalExtractor optionalExtractor = OptionalExtractor.create(); 32 | 33 | @Override 34 | public Optional> unapply(Optional value) { 35 | Optional opt = optionalExtractor.unapply(value); 36 | if (!opt.isPresent()) { 37 | return Optional.empty(); 38 | } 39 | 40 | List fields = new ArrayList<>(); 41 | fields.add(opt.get()); 42 | 43 | return Optional.of(fields); 44 | } 45 | 46 | @Override 47 | public Class getExtractorClass() { 48 | return optionalExtractor.getExtractorClass(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/OptionalNoneExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor0; 20 | 21 | import java.util.Optional; 22 | 23 | /** 24 | * An extractor for extracting an empty {@link Optional}. 25 | * 26 | * @author John Leacox 27 | */ 28 | public class OptionalNoneExtractor implements Extractor0> { 29 | private OptionalNoneExtractor() { 30 | } 31 | 32 | /** 33 | * Creates a new instance of {@link OptionalNoneExtractor}. 34 | */ 35 | public static OptionalNoneExtractor create() { 36 | return new OptionalNoneExtractor<>(); 37 | } 38 | 39 | @Override 40 | public boolean unapply(Optional t) { 41 | return !t.isPresent(); 42 | } 43 | 44 | @Override 45 | public Class getExtractorClass() { 46 | return Optional.class; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/OptionalNoneFieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | 21 | import java.util.Collections; 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * A field extractor for extracting the value in an empty {@link Optional}. 27 | * 28 | * @author John Leacox 29 | */ 30 | public class OptionalNoneFieldExtractor implements FieldExtractor> { 31 | private final OptionalNoneExtractor noneExtractor = OptionalNoneExtractor.create(); 32 | 33 | @Override 34 | public Optional> unapply(Optional value) { 35 | if (!noneExtractor.unapply(value)) { 36 | return Optional.empty(); 37 | } 38 | 39 | return Optional.of(Collections.emptyList()); 40 | } 41 | 42 | @Override 43 | public Class getExtractorClass() { 44 | return noneExtractor.getExtractorClass(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/PrimitiveExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor1; 20 | 21 | import java.util.Optional; 22 | 23 | /** 24 | * An extractor for extrating a primitive value. 25 | * 26 | * @author John Leacox 27 | */ 28 | public class PrimitiveExtractor implements Extractor1 { 29 | private final Class primitiveType; 30 | 31 | private PrimitiveExtractor(Class primitiveType) { 32 | this.primitiveType = primitiveType; 33 | } 34 | 35 | /** 36 | * Creates a new instance of {@link PrimitiveExtractor}. 37 | */ 38 | public static PrimitiveExtractor create(Class primitiveType) { 39 | return new PrimitiveExtractor<>(primitiveType); 40 | } 41 | 42 | @Override 43 | public Optional unapply(T t) { 44 | return Optional.ofNullable(t); 45 | } 46 | 47 | @Override 48 | public Class getExtractorClass() { 49 | return primitiveType; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/PrimitiveFieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * A field extractor for extracting a primitive value. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class PrimitiveFieldExtractor implements FieldExtractor { 31 | private final PrimitiveExtractor primitiveExtractor; 32 | 33 | PrimitiveFieldExtractor(Class primitiveType) { 34 | this.primitiveExtractor = PrimitiveExtractor.create(primitiveType); 35 | } 36 | 37 | @Override 38 | public Optional> unapply(T t) { 39 | Optional opt = primitiveExtractor.unapply(t); 40 | if (!opt.isPresent()) { 41 | return Optional.empty(); 42 | } 43 | 44 | List fields = new ArrayList<>(); 45 | fields.add(opt.get()); 46 | 47 | return Optional.of(fields); 48 | } 49 | 50 | @Override 51 | public Class getExtractorClass() { 52 | return primitiveExtractor.getExtractorClass(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Tuple1Extractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor1; 20 | import com.leacox.motif.tuple.Tuple1; 21 | 22 | import java.util.Optional; 23 | 24 | /** 25 | * An extract for extracting the fields of a {@link Tuple1}. 26 | * 27 | * @author John Leacox 28 | */ 29 | public class Tuple1Extractor implements Extractor1, A> { 30 | private Tuple1Extractor() { 31 | } 32 | 33 | /** 34 | * Creates a new instances of {@link Tuple1Extractor}. 35 | */ 36 | public static Tuple1Extractor create() { 37 | return new Tuple1Extractor<>(); 38 | } 39 | 40 | @Override 41 | public Optional unapply(Tuple1 tuple1) { 42 | return tuple1.first() == null ? Optional.empty() : Optional.ofNullable(tuple1.first()); 43 | } 44 | 45 | @Override 46 | public Class getExtractorClass() { 47 | return Tuple1.class; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Tuple1FieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | import com.leacox.motif.tuple.Tuple1; 21 | 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * Field extractor for {@link Tuple1}. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class Tuple1FieldExtractor implements FieldExtractor> { 31 | private final Tuple1Extractor tuple1Extractor = Tuple1Extractor.create(); 32 | 33 | @Override 34 | public Optional> unapply(Tuple1 value) { 35 | Optional opt = tuple1Extractor.unapply(value); 36 | if (!opt.isPresent()) { 37 | return Optional.empty(); 38 | } 39 | 40 | return Optional.of(value.toList()); 41 | } 42 | 43 | @Override 44 | public Class getExtractorClass() { 45 | return tuple1Extractor.getExtractorClass(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Tuple2Extractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor2; 20 | import com.leacox.motif.tuple.Tuple2; 21 | 22 | import java.util.Optional; 23 | 24 | /** 25 | * An extract for extracting the fields of a {@link Tuple2}. 26 | * 27 | * @author John Leacox 28 | */ 29 | public class Tuple2Extractor implements Extractor2, A, B> { 30 | private Tuple2Extractor() { 31 | } 32 | 33 | /** 34 | * Creates a new instances of {@link Tuple2Extractor}. 35 | */ 36 | public static Tuple2Extractor create() { 37 | return new Tuple2Extractor<>(); 38 | } 39 | 40 | @Override 41 | public Optional> unapply(Tuple2 tuple2) { 42 | return Optional.ofNullable(tuple2); 43 | } 44 | 45 | @Override 46 | public Class getExtractorClass() { 47 | return Tuple2.class; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Tuple2FieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | import com.leacox.motif.tuple.Tuple2; 21 | 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * Field extractor for {@link Tuple2}. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class Tuple2FieldExtractor implements FieldExtractor> { 31 | private final Tuple2Extractor tuple2Extractor = Tuple2Extractor.create(); 32 | 33 | @Override 34 | public Optional> unapply(Tuple2 value) { 35 | Optional> tuple2Opt = tuple2Extractor.unapply(value); 36 | if (!tuple2Opt.isPresent()) { 37 | return Optional.empty(); 38 | } 39 | 40 | return Optional.of(value.toList()); 41 | } 42 | 43 | @Override 44 | public Class getExtractorClass() { 45 | return tuple2Extractor.getExtractorClass(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Tuple3Extractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.Extractor3; 20 | import com.leacox.motif.tuple.Tuple3; 21 | 22 | import java.util.Optional; 23 | 24 | /** 25 | * An extract for extracting the fields of a {@link Tuple3}. 26 | * 27 | * @author John Leacox 28 | */ 29 | public class Tuple3Extractor implements Extractor3, A, B, C> { 30 | private Tuple3Extractor() { 31 | } 32 | 33 | /** 34 | * Creates a new instances of {@link Tuple3Extractor}. 35 | */ 36 | public static Tuple3Extractor create() { 37 | return new Tuple3Extractor<>(); 38 | } 39 | 40 | @Override 41 | public Optional> unapply(Tuple3 tuple3) { 42 | return Optional.ofNullable(tuple3); 43 | } 44 | 45 | @Override 46 | public Class getExtractorClass() { 47 | return Tuple3.class; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/Tuple3FieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | import com.leacox.motif.tuple.Tuple3; 21 | 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * Field extractor for {@link Tuple3}. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class Tuple3FieldExtractor implements FieldExtractor> { 31 | private final Tuple3Extractor tuple3Extractor = Tuple3Extractor.create(); 32 | 33 | @Override 34 | public Optional> unapply(Tuple3 value) { 35 | Optional> tuple3Opt = tuple3Extractor.unapply(value); 36 | if (!tuple3Opt.isPresent()) { 37 | return Optional.empty(); 38 | } 39 | 40 | return Optional.of(value.toList()); 41 | } 42 | 43 | @Override 44 | public Class getExtractorClass() { 45 | return tuple3Extractor.getExtractorClass(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/cases/TypeOfCases.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import static com.leacox.motif.extract.matchers.ArgumentMatchers.any; 20 | 21 | import com.leacox.motif.extract.DecomposableMatchBuilder1; 22 | import com.leacox.motif.extract.Extractor1; 23 | import com.leacox.motif.extract.FieldExtractor; 24 | import com.leacox.motif.extract.matchers.Matcher; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | import java.util.Optional; 29 | 30 | /** 31 | * Motif cases for matching on {@link Class} and extracting the value. 32 | * 33 | * @author John Leacox 34 | */ 35 | public final class TypeOfCases { 36 | private TypeOfCases() { 37 | } 38 | 39 | private static class TypeOfExtractor implements Extractor1 { 40 | private final Class expectedClass; 41 | 42 | TypeOfExtractor(Class expectedClass) { 43 | this.expectedClass = expectedClass; 44 | } 45 | 46 | @Override 47 | @SuppressWarnings("unchecked") 48 | public Optional unapply(Object o) { 49 | if (o == null) { 50 | return Optional.empty(); 51 | } 52 | 53 | return expectedClass.isAssignableFrom(o.getClass()) ? Optional.of((T) o) 54 | : Optional.empty(); 55 | } 56 | 57 | @Override 58 | public Class getExtractorClass() { 59 | return expectedClass; 60 | } 61 | } 62 | 63 | private static class TypeOfFieldExtractor implements FieldExtractor { 64 | private final TypeOfExtractor typeOfExtractor; 65 | 66 | TypeOfFieldExtractor(Class expectedClass) { 67 | this.typeOfExtractor = new TypeOfExtractor<>(expectedClass); 68 | } 69 | 70 | @Override 71 | public Optional> unapply(S value) { 72 | Optional opt = typeOfExtractor.unapply(value); 73 | if (!opt.isPresent()) { 74 | return Optional.empty(); 75 | } 76 | 77 | List fields = new ArrayList<>(); 78 | fields.add(opt.get()); 79 | 80 | return Optional.of(fields); 81 | } 82 | 83 | @Override 84 | public Class getExtractorClass() { 85 | return typeOfExtractor.getExtractorClass(); 86 | } 87 | } 88 | 89 | /** 90 | * Matches a value on {@link Class}. 91 | * 92 | *

If matched, the value is extracted. 93 | */ 94 | public static DecomposableMatchBuilder1 typeOf(Class clazz) { 95 | List> matchers = new ArrayList<>(); 96 | matchers.add(any()); // The extractor takes care of the matching 97 | 98 | return new DecomposableMatchBuilder1<>(matchers, 0, new TypeOfFieldExtractor<>(clazz)); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/DecomposableMatch0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.extract.matchers.Matcher; 20 | 21 | import java.util.List; 22 | import java.util.Optional; 23 | 24 | /** 25 | * A decomposable matcher that extracts 0 values. 26 | * 27 | * @author John Leacox 28 | */ 29 | final class DecomposableMatch0 implements Extractor0 { 30 | final List> fieldMatchers; 31 | final FieldExtractor fieldExtractor; 32 | 33 | DecomposableMatch0( 34 | List> fieldMatchers, FieldExtractor fieldExtractor) { 35 | this.fieldMatchers = fieldMatchers; 36 | this.fieldExtractor = fieldExtractor; 37 | } 38 | 39 | @Override 40 | public boolean unapply(T t) { 41 | Optional> fieldsOpt = fieldExtractor.unapply(t); 42 | if (!fieldsOpt.isPresent()) { 43 | return false; 44 | } 45 | 46 | List fields = fieldsOpt.get(); 47 | if (fieldMatchers.size() != fields.size()) { 48 | return false; 49 | } 50 | 51 | for (int i = 0; i < fieldMatchers.size(); i++) { 52 | if (!fieldMatchers.get(i).matches(fields.get(i))) { 53 | return false; 54 | } 55 | } 56 | 57 | return true; 58 | } 59 | 60 | @Override 61 | public Class getExtractorClass() { 62 | return fieldExtractor.getExtractorClass(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/DecomposableMatch1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.extract.matchers.Matcher; 20 | 21 | import java.util.List; 22 | import java.util.Optional; 23 | 24 | /** 25 | * A decomposable matcher that extracts 1 value. 26 | * 27 | * @author John Leacox 28 | */ 29 | final class DecomposableMatch1 implements Extractor1 { 30 | final List> fieldMatchers; 31 | final int extractedIndex; 32 | final FieldExtractor fieldExtractor; 33 | 34 | DecomposableMatch1( 35 | List> fieldMatchers, int extractedIndex, FieldExtractor fieldExtractor) { 36 | this.fieldMatchers = fieldMatchers; 37 | this.extractedIndex = extractedIndex; 38 | this.fieldExtractor = fieldExtractor; 39 | } 40 | 41 | @Override 42 | public Optional unapply(T t) { 43 | Optional> fieldsOpt = fieldExtractor.unapply(t); 44 | if (!fieldsOpt.isPresent()) { 45 | return Optional.empty(); 46 | } 47 | 48 | List fields = fieldsOpt.get(); 49 | if (fieldMatchers.size() != fields.size()) { 50 | return Optional.empty(); 51 | } 52 | 53 | for (int i = 0; i < fieldMatchers.size(); i++) { 54 | if (!fieldMatchers.get(i).matches(fields.get(i))) { 55 | return Optional.empty(); 56 | } 57 | } 58 | 59 | return Optional.of(getMatchedField(fields)); 60 | } 61 | 62 | @Override 63 | public Class getExtractorClass() { 64 | return fieldExtractor.getExtractorClass(); 65 | } 66 | 67 | private A getMatchedField(List fields) { 68 | A first = (A) fields.get(extractedIndex); 69 | return first; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/DecomposableMatch2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.extract.matchers.Matcher; 20 | import com.leacox.motif.tuple.Tuple2; 21 | 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * A decomposable matcher that extracts 2 values. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class DecomposableMatch2 implements Extractor2 { 31 | private final List> fieldMatchers; 32 | private final Tuple2 extractedIndexes; 33 | private final FieldExtractor fieldExtractor; 34 | 35 | DecomposableMatch2( 36 | List> fieldMatchers, Tuple2 extractedIndexes, 37 | FieldExtractor fieldExtractor) { 38 | this.fieldMatchers = fieldMatchers; 39 | this.extractedIndexes = extractedIndexes; 40 | this.fieldExtractor = fieldExtractor; 41 | } 42 | 43 | @Override 44 | public Optional> unapply(T t) { 45 | Optional> fieldsOpt = fieldExtractor.unapply(t); 46 | if (!fieldsOpt.isPresent()) { 47 | return Optional.empty(); 48 | } 49 | 50 | List fields = fieldsOpt.get(); 51 | if (fieldMatchers.size() != fields.size()) { 52 | return Optional.empty(); 53 | } 54 | 55 | for (int i = 0; i < fieldMatchers.size(); i++) { 56 | if (!fieldMatchers.get(i).matches(fields.get(i))) { 57 | return Optional.empty(); 58 | } 59 | } 60 | 61 | return Optional.of(getMatchedFields(fields)); 62 | } 63 | 64 | @Override 65 | public Class getExtractorClass() { 66 | return fieldExtractor.getExtractorClass(); 67 | } 68 | 69 | private Tuple2 getMatchedFields(List fields) { 70 | A first = (A) fields.get(extractedIndexes.first()); 71 | B second = (B) fields.get(extractedIndexes.second()); 72 | return Tuple2.of(first, second); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/DecomposableMatch3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.extract.matchers.Matcher; 20 | import com.leacox.motif.tuple.Tuple3; 21 | 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * A decomposable matcher that extracts 3 values. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class DecomposableMatch3 implements Extractor3 { 31 | private final List> fieldMatchers; 32 | private final Tuple3 extractedIndexes; 33 | private final FieldExtractor fieldExtractor; 34 | 35 | DecomposableMatch3( 36 | List> fieldMatchers, Tuple3 extractedIndexes, 37 | FieldExtractor fieldExtractor) { 38 | this.fieldMatchers = fieldMatchers; 39 | this.extractedIndexes = extractedIndexes; 40 | this.fieldExtractor = fieldExtractor; 41 | } 42 | 43 | @Override 44 | public Optional> unapply(T t) { 45 | Optional> fieldsOpt = fieldExtractor.unapply(t); 46 | if (!fieldsOpt.isPresent()) { 47 | return Optional.empty(); 48 | } 49 | 50 | List fields = fieldsOpt.get(); 51 | if (fieldMatchers.size() != fields.size()) { 52 | return Optional.empty(); 53 | } 54 | 55 | for (int i = 0; i < fieldMatchers.size(); i++) { 56 | if (!fieldMatchers.get(i).matches(fields.get(i))) { 57 | return Optional.empty(); 58 | } 59 | } 60 | 61 | return Optional.of(getMatchedFields(fields)); 62 | } 63 | 64 | @Override 65 | public Class getExtractorClass() { 66 | return fieldExtractor.getExtractorClass(); 67 | } 68 | 69 | private Tuple3 getMatchedFields(List fields) { 70 | A first = (A) fields.get(extractedIndexes.first()); 71 | B second = (B) fields.get(extractedIndexes.second()); 72 | C third = (C) fields.get(extractedIndexes.third()); 73 | return Tuple3.of(first, second, third); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/DecomposableMatchBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.extract.matchers.Matcher; 20 | 21 | import java.util.List; 22 | import java.util.Map; 23 | import java.util.TreeMap; 24 | 25 | /** 26 | * Abstract base class for all DecomposableMatchBuilder classes. 27 | * 28 | * @author John Leacox 29 | */ 30 | public abstract class DecomposableMatchBuilder { 31 | final List> fieldMatchers; 32 | final FieldExtractor fieldExtractor; 33 | 34 | DecomposableMatchBuilder(List> fieldMatchers, FieldExtractor fieldExtractor) { 35 | this.fieldMatchers = fieldMatchers; 36 | this.fieldExtractor = fieldExtractor; 37 | } 38 | 39 | protected TreeMap>> getChildMatchersByIndex( 40 | Map nestedBuildersByIndex) { 41 | TreeMap>> childMatchersByIndex = new TreeMap<>(); 42 | for (Map.Entry entry : nestedBuildersByIndex.entrySet()) { 43 | childMatchersByIndex.put(entry.getKey(), entry.getValue().fieldMatchers); 44 | } 45 | 46 | return childMatchersByIndex; 47 | } 48 | 49 | protected List> getChildMatchers( 50 | Map nestedBuildersByIndex) { 51 | TreeMap>> childMatchersByIndex = 52 | getChildMatchersByIndex(nestedBuildersByIndex); 53 | 54 | return NestedMatchers.buildNestedMatchers(this.fieldMatchers, childMatchersByIndex); 55 | } 56 | 57 | protected TreeMap getChildExtractorsByIndex( 58 | Map nestedBuildersByIndex) { 59 | TreeMap childExtractorsByIndex = new TreeMap<>(); 60 | for (Map.Entry entry : nestedBuildersByIndex.entrySet()) { 61 | childExtractorsByIndex.put(entry.getKey(), entry.getValue().fieldExtractor); 62 | } 63 | 64 | return childExtractorsByIndex; 65 | } 66 | 67 | protected NestedFieldExtractor getNestedFieldExtractor( 68 | Map buildersByIndex) { 69 | return new NestedFieldExtractor<>(fieldExtractor, getChildExtractorsByIndex(buildersByIndex)); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/DecomposableMatchBuilder0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.extract.matchers.Matcher; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * A decomposable match builder that extracts 0 parameters. 25 | * 26 | * @author John Leacox 27 | */ 28 | public final class DecomposableMatchBuilder0 extends DecomposableMatchBuilder { 29 | /** 30 | * Creates a new instance of {@link DecomposableMatchBuilder0}. 31 | */ 32 | public DecomposableMatchBuilder0( 33 | List> fieldMatchers, FieldExtractor fieldExtractor) { 34 | super(fieldMatchers, fieldExtractor); 35 | } 36 | 37 | /** 38 | * Builds a {@link DecomposableMatch0}. 39 | */ 40 | public DecomposableMatch0 build() { 41 | return new DecomposableMatch0<>(fieldMatchers, fieldExtractor); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/Extractor0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | /** 20 | * An extractor for types with 0 fields. 21 | * 22 | * @param the type to be extracted 23 | * 24 | * @author John Leacox 25 | */ 26 | public interface Extractor0 { 27 | /** 28 | * Returns true if {@code t} matches this extractor; otherwise false. 29 | */ 30 | boolean unapply(T t); 31 | 32 | /** 33 | * Returns the {@link Class} type that this extractor can extract. 34 | */ 35 | Class getExtractorClass(); 36 | } 37 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/Extractor1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import java.util.Optional; 20 | 21 | /** 22 | * An extractor for types with 1 fields. 23 | * 24 | * @param the type to be extracted 25 | * @param the type of the first extracted field 26 | * 27 | * @author John Leacox 28 | */ 29 | public interface Extractor1 { 30 | /** 31 | * Extracts the field of {@code t} into an {@link Optional} if it matches this extractor. 32 | * 33 | *

If {@code t} cannot be extracted then an {@link Optional#empty()} is returned. 34 | * 35 | * @param t the value to extract fields from 36 | * @return an {@link Optional} of the extracted field, or {@link Optional#empty()} if the field 37 | * cannot be extracted 38 | */ 39 | Optional unapply(T t); 40 | 41 | /** 42 | * Returns the {@link Class} type that this extractor can extract. 43 | */ 44 | Class getExtractorClass(); 45 | } 46 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/Extractor2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.tuple.Tuple2; 20 | 21 | import java.util.Optional; 22 | 23 | /** 24 | * An extractor for types with 2 fields. 25 | * 26 | * @param the type to be extracted 27 | * @param the type of the first extracted field 28 | * @param the type of the second extracted field 29 | * 30 | * @author John Leacox 31 | */ 32 | public interface Extractor2 { 33 | /** 34 | * Extracts the fields of {@code t} into an {@link Optional} {@link Tuple2} if it matches this 35 | * extractor. 36 | * 37 | *

If {@code t} cannot be extracted then an {@link Optional#empty()} is returned. 38 | * 39 | * @param t the value to extract fields from 40 | * @return an {@link Optional} of the extracted fields, or {@link Optional#empty()} if the fields 41 | * cannot be extracted 42 | */ 43 | Optional> unapply(T t); 44 | 45 | /** 46 | * Returns the {@link Class} type that this extractor can extract. 47 | */ 48 | Class getExtractorClass(); 49 | } 50 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/Extractor3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.tuple.Tuple3; 20 | 21 | import java.util.Optional; 22 | 23 | /** 24 | * An extractor for types with 3 fields. 25 | * 26 | * @param the type to be extracted 27 | * @param the type of the first extracted field 28 | * @param the type of the second extracted field 29 | * @param the type of the third extracted field 30 | * 31 | * @author John Leacox 32 | */ 33 | public interface Extractor3 { 34 | /** 35 | * Extracts the fields of {@code t} into an {@link Optional} {@link Tuple3} if it matches this 36 | * extractor. 37 | * 38 | *

If {@code t} cannot be extracted then an {@link Optional#empty()} is returned. 39 | * 40 | * @param t the value to extract fields from 41 | * @return an {@link Optional} of the extracted fields, or {@link Optional#empty()} if the fields 42 | * cannot be extracted 43 | */ 44 | Optional> unapply(T t); 45 | 46 | /** 47 | * Returns the {@link Class} type that this extractor can extract. 48 | */ 49 | Class getExtractorClass(); 50 | } 51 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/FieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import java.util.List; 20 | import java.util.Optional; 21 | 22 | /** 23 | * An extractor for extracting an objects fields into an {@link Optional} of {@link List}. 24 | * 25 | * @author John Leacox 26 | */ 27 | public interface FieldExtractor { 28 | Optional> unapply(T value); 29 | 30 | Class getExtractorClass(); 31 | } 32 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/NestedFieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.Optional; 23 | import java.util.TreeMap; 24 | 25 | /** 26 | * A field extractor for extracting nested matches. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class NestedFieldExtractor implements FieldExtractor { 31 | private final FieldExtractor parent; 32 | private final Map childExtractorsByIndex; 33 | 34 | NestedFieldExtractor( 35 | FieldExtractor parent, TreeMap childExtractorsByIndex) { 36 | this.parent = parent; 37 | this.childExtractorsByIndex = childExtractorsByIndex; 38 | } 39 | 40 | @SuppressWarnings("unchecked") 41 | @Override 42 | public Optional> unapply(T value) { 43 | Optional> fieldsOpt = parent.unapply(value); 44 | 45 | if (!fieldsOpt.isPresent()) { 46 | return Optional.empty(); 47 | } 48 | 49 | List fields = fieldsOpt.get(); 50 | int currentIndex = 0; 51 | List newFields = new ArrayList<>(); 52 | for (Map.Entry entry : childExtractorsByIndex.entrySet()) { 53 | int childIndex = entry.getKey(); 54 | FieldExtractor child = entry.getValue(); 55 | if (!child.getExtractorClass().isAssignableFrom(fields.get(childIndex).getClass())) { 56 | return Optional.empty(); 57 | } 58 | 59 | @SuppressWarnings("unchecked") 60 | Optional> childFieldsOpt = child.unapply(fields.get(childIndex)); 61 | 62 | if (!childFieldsOpt.isPresent()) { 63 | return Optional.empty(); 64 | } 65 | 66 | List childFields = childFieldsOpt.get(); 67 | newFields.addAll(fields.subList(currentIndex, childIndex)); 68 | newFields.addAll(childFields); 69 | 70 | currentIndex = childIndex + 1; 71 | } 72 | 73 | newFields.addAll(fields.subList(currentIndex, fields.size())); 74 | 75 | return Optional.of(newFields); 76 | } 77 | 78 | @Override 79 | public Class getExtractorClass() { 80 | return parent.getExtractorClass(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/NestedMatchers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract; 18 | 19 | import com.leacox.motif.extract.matchers.Matcher; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.Map; 24 | import java.util.TreeMap; 25 | 26 | /** 27 | * Static utility methods for working with nested matches. 28 | * 29 | * @author John Leacox 30 | */ 31 | final class NestedMatchers { 32 | private NestedMatchers() { 33 | } 34 | 35 | static List> buildNestedMatchers( 36 | List> original, 37 | TreeMap>> childMatchersByIndex) { 38 | List> matchers = new ArrayList<>(); 39 | 40 | int currentIndex = 0; 41 | for (Map.Entry>> entry : childMatchersByIndex.entrySet()) { 42 | int childIndex = entry.getKey(); 43 | List> childMatchers = entry.getValue(); 44 | 45 | matchers.addAll(original.subList(currentIndex, childIndex)); 46 | matchers.addAll(childMatchers); 47 | 48 | currentIndex = childIndex + 1; 49 | } 50 | 51 | matchers.addAll(original.subList(currentIndex, original.size())); 52 | 53 | return matchers; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/matchers/Any.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract.matchers; 18 | 19 | /** 20 | * A wildcard matcher that matches anything. 21 | * 22 | * @author John Leacox 23 | */ 24 | class Any implements Matcher { 25 | /** 26 | * A singleton instance of an {@link Any} matcher. 27 | */ 28 | public static final Any ANY = new Any(); 29 | 30 | private Any() { 31 | } 32 | 33 | @Override 34 | public boolean matches(Object arg) { 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/matchers/ArgumentMatchers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract.matchers; 18 | 19 | /** 20 | * Matchers for use in creates matching cases. 21 | * 22 | *

These generally shouldn't be used direct except when creating 'Cases' classes like 23 | * {@link com.leacox.motif.cases.OptionalCases}. 24 | * 25 | * @author John Leacox 26 | */ 27 | public class ArgumentMatchers { 28 | private ArgumentMatchers() { 29 | } 30 | 31 | /** 32 | * Returns a wildcard matcher. 33 | */ 34 | @SuppressWarnings("unchecked") 35 | public static Matcher any() { 36 | return Any.ANY; 37 | } 38 | 39 | /** 40 | * Returns an equals matcher for the given value. 41 | */ 42 | @SuppressWarnings("unchecked") 43 | public static Matcher eq(T value) { 44 | return (Matcher) new Equals(value); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/matchers/Equals.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract.matchers; 18 | 19 | import java.util.Objects; 20 | 21 | /** 22 | * A matcher that checks equality. 23 | * 24 | * @author John Leacox 25 | */ 26 | class Equals implements Matcher { 27 | private final Object expected; 28 | 29 | public Equals(Object expected) { 30 | this.expected = expected; 31 | } 32 | 33 | @Override 34 | public boolean matches(Object arg) { 35 | // TODO: Is special logic needed for arrays? 36 | return Objects.equals(expected, arg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/matchers/Matcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract.matchers; 18 | 19 | /** 20 | * An interface for argument matchers when building motif pattern cases. 21 | * 22 | * @author John Leacox 23 | */ 24 | public interface Matcher { 25 | boolean matches(Object arg); 26 | } 27 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/util/Lists.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract.util; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | /** 24 | * A utility class for quickly building lists for internal motif and extension usage. 25 | * 26 | *

Caution: This class is not meant to be used outside of internal motif and motif extensions. 27 | * In general {@code Guava} should be used instead of this. 28 | * 29 | * @author John Leacox 30 | */ 31 | public final class Lists { 32 | private Lists() { 33 | } 34 | 35 | /** 36 | * Returns the empty list. 37 | */ 38 | public static List of() { 39 | return Collections.emptyList(); 40 | } 41 | 42 | /** 43 | * Returns a list with a single entry. 44 | */ 45 | public static List of(E e1) { 46 | List list = new ArrayList<>(); 47 | list.add(e1); 48 | return list; 49 | } 50 | 51 | /** 52 | * Returns a list of the given elements, in order. 53 | */ 54 | public static List of(E e1, E e2) { 55 | List list = new ArrayList<>(); 56 | list.add(e1); 57 | list.add(e2); 58 | return list; 59 | } 60 | 61 | /** 62 | * Returns a list of the given elements, in order. 63 | */ 64 | public static List of(E e1, E e2, E e3) { 65 | List list = new ArrayList<>(); 66 | list.add(e1); 67 | list.add(e2); 68 | list.add(e3); 69 | return list; 70 | } 71 | 72 | /** 73 | * Returns a list of the given elements, in order. 74 | */ 75 | public static List of(E e1, E e2, E e3, E e4) { 76 | List list = new ArrayList<>(); 77 | list.add(e1); 78 | list.add(e2); 79 | list.add(e3); 80 | list.add(e4); 81 | return list; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/extract/util/Maps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.extract.util; 18 | 19 | import java.util.TreeMap; 20 | 21 | /** 22 | * A utility class for quickly building maps for internal motif and extension usage. 23 | * 24 | *

Caution: This class is not meant to be used outside of internal motif and motif extensions. 25 | * In general {@code Guava} should be used instead of this. 26 | * 27 | * @author John Leacox 28 | */ 29 | public final class Maps { 30 | private Maps() { 31 | } 32 | 33 | /** 34 | * Returns a {@link TreeMap} with a single entry. 35 | */ 36 | public static TreeMap treeMapOf(K k1, V v1) { 37 | TreeMap treeMap = new TreeMap<>(); 38 | treeMap.put(k1, v1); 39 | return treeMap; 40 | } 41 | 42 | /** 43 | * Returns a {@link TreeMap} of the given entries, in order. 44 | */ 45 | public static TreeMap treeMapOf(K k1, V v1, K k2, V v2) { 46 | TreeMap treeMap = new TreeMap<>(); 47 | treeMap.put(k1, v1); 48 | treeMap.put(k2, v2); 49 | return treeMap; 50 | } 51 | 52 | /** 53 | * Returns a {@link TreeMap} of the given entries, in order. 54 | */ 55 | public static TreeMap treeMapOf(K k1, V v1, K k2, V v2, K k3, V v3) { 56 | TreeMap treeMap = new TreeMap<>(); 57 | treeMap.put(k1, v1); 58 | treeMap.put(k2, v2); 59 | treeMap.put(k3, v3); 60 | return treeMap; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/function/Consumer0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.function; 18 | 19 | /** 20 | * An operation on zero arguments that returns no result. 21 | * 22 | * @author John Leacox 23 | */ 24 | @FunctionalInterface 25 | public interface Consumer0 { 26 | /** 27 | * Performs this operation with no arguments. 28 | */ 29 | void accept(); 30 | } 31 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/function/Consumer2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.function; 18 | 19 | /** 20 | * An operation on two arguments that returns no result. 21 | * 22 | * @param the type of argument one 23 | * @param the type of argument two 24 | * 25 | * @author John Leacox 26 | */ 27 | @FunctionalInterface 28 | public interface Consumer2 { 29 | /** 30 | * Performs this operation on the given arguments. 31 | * 32 | * @param a the input argument one 33 | * @param b the input argument two 34 | */ 35 | void accept(A a, B b); 36 | } 37 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/function/Consumer3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.function; 18 | 19 | /** 20 | * An operation on three arguments that returns no result. 21 | * 22 | * @param the type of argument one 23 | * @param the type of argument two 24 | * @param the type of argument three 25 | * 26 | * @author John Leacox 27 | */ 28 | @FunctionalInterface 29 | public interface Consumer3 { 30 | /** 31 | * Performs this operation on the given arguments. 32 | * 33 | * @param a the input argument one 34 | * @param b the input argument two 35 | * @param c the input argument three 36 | */ 37 | void accept(A a, B b, C c); 38 | } 39 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/function/Function2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.function; 18 | 19 | /** 20 | * A function of two arguments. 21 | * 22 | * @param the type of argument one 23 | * @param the type of argument two 24 | * @param the type of the result 25 | * @author John Leacox 26 | */ 27 | @FunctionalInterface 28 | public interface Function2 { 29 | /** 30 | * Applies this function to the given arguments. 31 | * 32 | * @param a the function argument one 33 | * @param b the function argument two 34 | * @return the function result 35 | */ 36 | R apply(A a, B b); 37 | } 38 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/function/Function3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.function; 18 | 19 | /** 20 | * A function of three arguments. 21 | * 22 | * @param the type of argument one 23 | * @param the type of argument two 24 | * @param the type of argument three 25 | * @param the type of the result 26 | * 27 | * @author John Leacox 28 | */ 29 | @FunctionalInterface 30 | public interface Function3 { 31 | /** 32 | * Applies this function to the given arguments. 33 | * 34 | * @param a the function argument one 35 | * @param b the function argument two 36 | * @param c the function argument three 37 | * @return the function result 38 | */ 39 | R apply(A a, B b, C c); 40 | } 41 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/ConsumablePattern.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import java.util.function.Consumer; 20 | import java.util.function.Function; 21 | 22 | /** 23 | * A pattern used internally to pair up matchers and consumable actions. 24 | * 25 | * @author John Leacox 26 | */ 27 | interface ConsumablePattern { 28 | boolean matches(T value); 29 | 30 | void consume(T value); 31 | 32 | static ConsumablePattern of(Function matcher, Consumer consumer) { 33 | return new ConsumablePattern() { 34 | @Override 35 | public boolean matches(T value) { 36 | return matcher.apply(value); 37 | } 38 | 39 | @Override 40 | public void consume(T value) { 41 | consumer.accept(value); 42 | } 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/IdentityFieldExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.FieldExtractor; 20 | 21 | import java.util.Collections; 22 | import java.util.List; 23 | import java.util.Optional; 24 | 25 | /** 26 | * A field extractor that returns a singleton list containing only the original value. 27 | * 28 | * @author John Leacox 29 | */ 30 | final class IdentityFieldExtractor implements FieldExtractor { 31 | @Override 32 | public Optional> unapply(T value) { 33 | return Optional.of(Collections.singletonList(value)); 34 | } 35 | 36 | @Override 37 | public Class getExtractorClass() { 38 | return Object.class; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/InitialMatching0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor0; 20 | import com.leacox.motif.function.Consumer0; 21 | 22 | import java.util.function.Supplier; 23 | 24 | /** 25 | * Fluent API for specifying an action to take on a match with 0 parameters. 26 | * 27 | * @author John Leacox 28 | */ 29 | public final class InitialMatching0 extends Matching0 { 30 | private final T value; 31 | 32 | InitialMatching0(Extractor0 extractor, T value) { 33 | super(extractor); 34 | 35 | this.value = value; 36 | } 37 | 38 | /** 39 | * Sets a {@link Supplier} to execute if this matches. 40 | */ 41 | public FluentMatchingR get(Supplier supplier) { 42 | return get(new FluentMatchingR<>(value), supplier); 43 | } 44 | 45 | /** 46 | * Sets a {@link Consumer0} to execute if this matches. 47 | */ 48 | public FluentMatchingC then(Consumer0 consumer) { 49 | return then(new FluentMatchingC<>(value), consumer); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/InitialMatching1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor1; 20 | 21 | import java.util.function.Consumer; 22 | import java.util.function.Function; 23 | 24 | /** 25 | * Fluent API for specifying an action to take on a match with 1 parameter. 26 | * 27 | * @author John Leacox 28 | */ 29 | public final class InitialMatching1 extends Matching1 { 30 | private final T value; 31 | 32 | InitialMatching1(Extractor1 extractor, T value) { 33 | super(extractor); 34 | 35 | this.value = value; 36 | } 37 | 38 | /** 39 | * Sets a {@link Function} to execute if this matches. 40 | */ 41 | public FluentMatchingR get(Function function) { 42 | return get(new FluentMatchingR<>(value), function); 43 | } 44 | 45 | /** 46 | * Sets a {@link Consumer} to execute if this matches. 47 | */ 48 | public FluentMatchingC then(Consumer consumer) { 49 | return then(new FluentMatchingC<>(value), consumer); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/InitialMatching2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor2; 20 | import com.leacox.motif.function.Consumer2; 21 | import com.leacox.motif.function.Function2; 22 | 23 | /** 24 | * Fluent API for specifying an action to take on a match with 2 parameters. 25 | * 26 | * @author John Leacox 27 | */ 28 | public final class InitialMatching2 extends Matching2 { 29 | private final T value; 30 | 31 | InitialMatching2(Extractor2 extractor, T value) { 32 | super(extractor); 33 | 34 | this.value = value; 35 | } 36 | 37 | /** 38 | * Sets a {@link Function2} to execute if this matches. 39 | */ 40 | public FluentMatchingR get(Function2 function) { 41 | return get(new FluentMatchingR<>(value), function); 42 | } 43 | 44 | /** 45 | * Sets a {@link Consumer2} to execute if this matches. 46 | */ 47 | public FluentMatchingC then(Consumer2 consumer) { 48 | return then(new FluentMatchingC<>(value), consumer); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/InitialMatching3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor3; 20 | import com.leacox.motif.function.Consumer3; 21 | import com.leacox.motif.function.Function3; 22 | 23 | /** 24 | * Fluent API for specifying an action to take on a match with 3 parameters. 25 | * 26 | * @author John Leacox 27 | */ 28 | public final class InitialMatching3 extends Matching3 { 29 | private final T value; 30 | 31 | InitialMatching3(Extractor3 extractor, T value) { 32 | super(extractor); 33 | 34 | this.value = value; 35 | } 36 | 37 | /** 38 | * Sets a {@link Function3} to execute if this matches. 39 | */ 40 | public FluentMatchingR get(Function3 function) { 41 | return get(new FluentMatchingR<>(value), function); 42 | } 43 | 44 | /** 45 | * Sets a {@link Consumer3} to execute if this matches. 46 | */ 47 | public FluentMatchingC then(Consumer3 consumer) { 48 | return then(new FluentMatchingC<>(value), consumer); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/Matching0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor0; 20 | import com.leacox.motif.function.Consumer0; 21 | 22 | import java.util.function.Supplier; 23 | 24 | /** 25 | * Abstract matching class for matching cases that extract 0 parameters. 26 | * 27 | * @author John Leacox 28 | */ 29 | abstract class Matching0 { 30 | private final Extractor0 extractor; 31 | 32 | Matching0( 33 | Extractor0 extractor) { 34 | this.extractor = extractor; 35 | } 36 | 37 | FluentMatchingR get( 38 | FluentMatchingR fluentMatchingR, Supplier supplier) { 39 | fluentMatchingR.addPattern( 40 | Pattern.of( 41 | t -> extractor.getExtractorClass().isAssignableFrom(t.getClass()) && extractor 42 | .unapply((U) t), t -> supplier.get())); 43 | 44 | return fluentMatchingR; 45 | } 46 | 47 | FluentMatchingC then(FluentMatchingC fluentMatchingC, Consumer0 consumer) { 48 | fluentMatchingC.addPattern( 49 | ConsumablePattern.of( 50 | t -> extractor.getExtractorClass().isAssignableFrom(t.getClass()) && extractor 51 | .unapply((U) t), t -> consumer.accept())); 52 | 53 | return fluentMatchingC; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/Matching1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor1; 20 | 21 | import java.util.function.Consumer; 22 | import java.util.function.Function; 23 | 24 | /** 25 | * Abstract matching class for matching cases that extract 1 parameter. 26 | * 27 | * @author John Leacox 28 | */ 29 | abstract class Matching1 { 30 | private final Extractor1 extractor; 31 | 32 | Matching1( 33 | Extractor1 extractor) { 34 | this.extractor = extractor; 35 | } 36 | 37 | FluentMatchingR get( 38 | FluentMatchingR fluentMatchingR, Function function) { 39 | fluentMatchingR.addPattern( 40 | Pattern.of( 41 | t -> extractor.getExtractorClass().isAssignableFrom(t.getClass()) && extractor 42 | .unapply((U) t).isPresent(), 43 | t -> { 44 | A a = extractor.unapply((U) t).get(); 45 | return function.apply(a); 46 | } 47 | ) 48 | ); 49 | 50 | return fluentMatchingR; 51 | } 52 | 53 | FluentMatchingC then(FluentMatchingC fluentMatchingC, Consumer consumer) { 54 | fluentMatchingC.addPattern( 55 | ConsumablePattern.of( 56 | t -> extractor.getExtractorClass().isAssignableFrom(t.getClass()) && extractor 57 | .unapply((U) t).isPresent(), 58 | t -> { 59 | A a = extractor.unapply((U) t).get(); 60 | consumer.accept(a); 61 | } 62 | ) 63 | ); 64 | 65 | return fluentMatchingC; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/Matching2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor2; 20 | import com.leacox.motif.function.Consumer2; 21 | import com.leacox.motif.function.Function2; 22 | import com.leacox.motif.tuple.Tuple2; 23 | 24 | /** 25 | * Abstract matching class for matching cases that extract 2 parameters. 26 | * 27 | * @author John Leacox 28 | */ 29 | abstract class Matching2 { 30 | private final Extractor2 extractor; 31 | 32 | Matching2(Extractor2 extractor) { 33 | this.extractor = extractor; 34 | } 35 | 36 | FluentMatchingR get( 37 | FluentMatchingR fluentMatchingR, Function2 function) { 38 | fluentMatchingR.addPattern( 39 | Pattern.of( 40 | t -> extractor.getExtractorClass().isAssignableFrom(t.getClass()) && extractor 41 | .unapply((U) t).isPresent(), 42 | t -> { 43 | Tuple2 tuple2 = extractor.unapply((U) t).get(); 44 | return function.apply(tuple2.first(), tuple2.second()); 45 | } 46 | ) 47 | ); 48 | 49 | return fluentMatchingR; 50 | } 51 | 52 | FluentMatchingC then(FluentMatchingC fluentMatchingC, Consumer2 consumer) { 53 | fluentMatchingC.addPattern( 54 | ConsumablePattern.of( 55 | t -> extractor.getExtractorClass().isAssignableFrom(t.getClass()) && extractor 56 | .unapply((U) t).isPresent(), 57 | t -> { 58 | Tuple2 tuple2 = extractor.unapply((U) t).get(); 59 | consumer.accept(tuple2.first(), tuple2.second()); 60 | } 61 | ) 62 | ); 63 | 64 | return fluentMatchingC; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/Matching3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor3; 20 | import com.leacox.motif.function.Consumer3; 21 | import com.leacox.motif.function.Function3; 22 | import com.leacox.motif.tuple.Tuple3; 23 | 24 | /** 25 | * Abstract matching class for matching cases that extract 3 parameters. 26 | * 27 | * @author John Leacox 28 | */ 29 | abstract class Matching3 { 30 | private final Extractor3 extractor; 31 | 32 | Matching3(Extractor3 extractor) { 33 | this.extractor = extractor; 34 | } 35 | 36 | FluentMatchingR get( 37 | FluentMatchingR fluentMatchingR, Function3 function) { 38 | fluentMatchingR.addPattern( 39 | Pattern.of( 40 | t -> extractor.getExtractorClass().isAssignableFrom(t.getClass()) && extractor 41 | .unapply((U) t).isPresent(), 42 | t -> { 43 | Tuple3 tuple3 = extractor.unapply((U) t).get(); 44 | return function.apply(tuple3.first(), tuple3.second(), tuple3.third()); 45 | } 46 | ) 47 | ); 48 | 49 | return fluentMatchingR; 50 | } 51 | 52 | FluentMatchingC then(FluentMatchingC fluentMatchingC, Consumer3 consumer) { 53 | fluentMatchingC.addPattern( 54 | ConsumablePattern.of( 55 | t -> extractor.getExtractorClass().isAssignableFrom(t.getClass()) && extractor 56 | .unapply((U) t).isPresent(), 57 | t -> { 58 | Tuple3 tuple3 = extractor.unapply((U) t).get(); 59 | consumer.accept(tuple3.first(), tuple3.second(), tuple3.third()); 60 | } 61 | ) 62 | ); 63 | 64 | return fluentMatchingC; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/OngoingMatchingC0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor0; 20 | import com.leacox.motif.function.Consumer0; 21 | 22 | /** 23 | * Fluent API for specifying an action to take on a match with 0 parameters. 24 | * 25 | * @author John Leacox 26 | */ 27 | public final class OngoingMatchingC0 extends Matching0 { 28 | private final FluentMatchingC fluentMatchingC; 29 | 30 | OngoingMatchingC0(FluentMatchingC fluentMatchingC, Extractor0 extractor) { 31 | super(extractor); 32 | 33 | this.fluentMatchingC = fluentMatchingC; 34 | } 35 | 36 | /** 37 | * Sets a {@link Consumer0} to execute if this matches. 38 | */ 39 | public FluentMatchingC then(Consumer0 consumer) { 40 | return then(fluentMatchingC, consumer); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/OngoingMatchingC1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor1; 20 | 21 | import java.util.function.Consumer; 22 | 23 | /** 24 | * Fluent API for specifying an action to take on a match with 1 parameter. 25 | * 26 | * @author John Leacox 27 | */ 28 | public final class OngoingMatchingC1 extends Matching1 { 29 | private final FluentMatchingC fluentMatchingC; 30 | 31 | OngoingMatchingC1(FluentMatchingC fluentMatchingC, Extractor1 extractor) { 32 | super(extractor); 33 | 34 | this.fluentMatchingC = fluentMatchingC; 35 | } 36 | 37 | /** 38 | * Sets a {@link Consumer} to execute if this matches. 39 | */ 40 | public FluentMatchingC then(Consumer consumer) { 41 | return then(fluentMatchingC, consumer); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/OngoingMatchingC2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor2; 20 | import com.leacox.motif.function.Consumer2; 21 | 22 | /** 23 | * Fluent API for specifying an action to take on a match with 2 parameters. 24 | * 25 | * @author John Leacox 26 | */ 27 | public final class OngoingMatchingC2 extends Matching2 { 28 | private final FluentMatchingC fluentMatchingC; 29 | 30 | OngoingMatchingC2(FluentMatchingC fluentMatchingC, Extractor2 extractor) { 31 | super(extractor); 32 | 33 | this.fluentMatchingC = fluentMatchingC; 34 | } 35 | 36 | /** 37 | * Sets a {@link Consumer2} to execute if this matches. 38 | */ 39 | public FluentMatchingC then(Consumer2 consumer) { 40 | return then(fluentMatchingC, consumer); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/OngoingMatchingC3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor3; 20 | import com.leacox.motif.function.Consumer3; 21 | 22 | /** 23 | * Fluent API for specifying an action to take on a match with 3 parameters. 24 | * 25 | * @author John Leacox 26 | */ 27 | public class OngoingMatchingC3 extends Matching3 { 28 | private final FluentMatchingC fluentMatchingC; 29 | 30 | OngoingMatchingC3(FluentMatchingC fluentMatchingC, Extractor3 extractor) { 31 | super(extractor); 32 | 33 | this.fluentMatchingC = fluentMatchingC; 34 | } 35 | 36 | /** 37 | * Sets a {@link Consumer3} to execute if this matches. 38 | */ 39 | public FluentMatchingC then(Consumer3 consumer) { 40 | return then(fluentMatchingC, consumer); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/OngoingMatchingR0.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor0; 20 | 21 | import java.util.function.Supplier; 22 | 23 | /** 24 | * Fluent API for specifying an action to take on a match with 0 parameters. 25 | * 26 | * @author John Leacox 27 | */ 28 | public final class OngoingMatchingR0 extends Matching0 { 29 | private final FluentMatchingR fluentMatchingR; 30 | 31 | OngoingMatchingR0(FluentMatchingR fluentMatchingR, Extractor0 extractor) { 32 | super(extractor); 33 | this.fluentMatchingR = fluentMatchingR; 34 | } 35 | 36 | /** 37 | * Sets a {@link Supplier} to execute if this matches. 38 | */ 39 | public FluentMatchingR get(Supplier supplier) { 40 | return get(fluentMatchingR, supplier); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/OngoingMatchingR1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor1; 20 | 21 | import java.util.function.Function; 22 | 23 | /** 24 | * Fluent API for specifying an action to take on a match with 1 parameter. 25 | * 26 | * @author John Leacox 27 | */ 28 | public final class OngoingMatchingR1 extends Matching1 { 29 | private final FluentMatchingR fluentMatchingR; 30 | 31 | OngoingMatchingR1(FluentMatchingR fluentMatchingR, Extractor1 extractor) { 32 | super(extractor); 33 | 34 | this.fluentMatchingR = fluentMatchingR; 35 | } 36 | 37 | /** 38 | * Sets a {@link Function} to execute if this matches. 39 | */ 40 | public FluentMatchingR get(Function function) { 41 | return get(fluentMatchingR, function); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/OngoingMatchingR2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor2; 20 | import com.leacox.motif.function.Function2; 21 | 22 | /** 23 | * Fluent API for specifying an action to take on a match with 2 parameters. 24 | * 25 | * @author John Leacox 26 | */ 27 | public final class OngoingMatchingR2 extends Matching2 { 28 | private final FluentMatchingR fluentMatchingR; 29 | 30 | OngoingMatchingR2(FluentMatchingR fluentMatchingR, Extractor2 extractor) { 31 | super(extractor); 32 | 33 | this.fluentMatchingR = fluentMatchingR; 34 | } 35 | 36 | /** 37 | * Sets a {@link Function2} to execute if this matches. 38 | */ 39 | public FluentMatchingR get(Function2 function) { 40 | return get(fluentMatchingR, function); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/OngoingMatchingR3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import com.leacox.motif.extract.Extractor3; 20 | import com.leacox.motif.function.Function3; 21 | 22 | /** 23 | * Fluent API for specifying an action to take on a match with 3 parameters. 24 | * 25 | * @author John Leacox 26 | */ 27 | public final class OngoingMatchingR3 extends Matching3 { 28 | private final FluentMatchingR fluentMatchingR; 29 | 30 | OngoingMatchingR3(FluentMatchingR fluentMatchingR, Extractor3 extractor) { 31 | super(extractor); 32 | 33 | this.fluentMatchingR = fluentMatchingR; 34 | } 35 | 36 | /** 37 | * Sets a {@link Function3} to execute if this matches. 38 | */ 39 | public FluentMatchingR get(Function3 function) { 40 | return get(fluentMatchingR, function); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/matching/Pattern.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.matching; 18 | 19 | import java.util.function.Function; 20 | 21 | /** 22 | * A pattern used internally to pair up matchers and actions. 23 | * 24 | * @author John Leacox 25 | */ 26 | interface Pattern { 27 | boolean matches(T value); 28 | 29 | R apply(T value); 30 | 31 | static Pattern of(Function matcher, Function function) { 32 | return new Pattern() { 33 | @Override 34 | public boolean matches(T value) { 35 | return matcher.apply(value); 36 | } 37 | 38 | @Override 39 | public R apply(T value) { 40 | return function.apply(value); 41 | } 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/tuple/Tuple.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.tuple; 18 | 19 | import java.util.Arrays; 20 | import java.util.Collections; 21 | import java.util.List; 22 | import java.util.Objects; 23 | 24 | /** 25 | * Abstract base class for all tuple classes. 26 | * 27 | *

This class implements {@link Object#equals(Object)}, {@link Object#hashCode()} and 28 | * {@link Object#toString()} for all tuples. 29 | * 30 | * @author John Leacox 31 | */ 32 | public abstract class Tuple { 33 | private final List values; 34 | 35 | protected Tuple(Object... values) { 36 | this.values = Collections.unmodifiableList(Arrays.asList(values)); 37 | } 38 | 39 | public List toList() { 40 | return values; 41 | } 42 | 43 | @Override 44 | public boolean equals(Object o) { 45 | if (this == o) { 46 | return true; 47 | } 48 | if (!(o instanceof Tuple)) { 49 | return false; 50 | } 51 | Tuple tuple = (Tuple) o; 52 | return Objects.equals(values, tuple.values); 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | return Objects.hash(values); 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return "(" + values.stream().reduce((t, u) -> t + "," + u).get() + ")"; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/tuple/Tuple1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.tuple; 18 | 19 | /** 20 | * A tuple with a single value. 21 | * 22 | * @author John Leacox 23 | */ 24 | public final class Tuple1 extends Tuple { 25 | private final A a; 26 | 27 | private Tuple1(A a) { 28 | super(a); 29 | 30 | this.a = a; 31 | } 32 | 33 | /** 34 | * Creates a new instance of {@link Tuple1} with the specified value. 35 | */ 36 | public static Tuple1 of(A a) { 37 | return new Tuple1<>(a); 38 | } 39 | 40 | /** 41 | * Returns the first and only value. 42 | */ 43 | public A first() { 44 | return a; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/tuple/Tuple2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.tuple; 18 | 19 | /** 20 | * A tuple with two values. 21 | * 22 | * @author John Leacox 23 | */ 24 | public final class Tuple2 extends Tuple { 25 | private final A a; 26 | private final B b; 27 | 28 | private Tuple2(A a, B b) { 29 | super(a, b); 30 | 31 | this.a = a; 32 | this.b = b; 33 | } 34 | 35 | /** 36 | * Creates a new instance of {@link Tuple2} with the specified values. 37 | */ 38 | public static Tuple2 of(A a, B b) { 39 | return new Tuple2<>(a, b); 40 | } 41 | 42 | /** 43 | * Returns the first value. 44 | */ 45 | public A first() { 46 | return a; 47 | } 48 | 49 | /** 50 | * Returns the second value. 51 | */ 52 | public B second() { 53 | return b; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /motif/src/main/java/com/leacox/motif/tuple/Tuple3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.tuple; 18 | 19 | /** 20 | * A tuple with three values. 21 | * 22 | * @author John Leacox 23 | */ 24 | public final class Tuple3 extends Tuple { 25 | private final A a; 26 | private final B b; 27 | private final C c; 28 | 29 | private Tuple3(A a, B b, C c) { 30 | super(a, b, c); 31 | 32 | this.a = a; 33 | this.b = b; 34 | this.c = c; 35 | } 36 | 37 | /** 38 | * Creates a new instance of {@link Tuple2} with the specified values. 39 | */ 40 | public static Tuple3 of(A a, B b, C c) { 41 | return new Tuple3<>(a, b, c); 42 | } 43 | 44 | /** 45 | * Returns the first value. 46 | */ 47 | public A first() { 48 | return a; 49 | } 50 | 51 | /** 52 | * Returns the second value. 53 | */ 54 | public B second() { 55 | return b; 56 | } 57 | 58 | /** 59 | * Returns the third value. 60 | */ 61 | public C third() { 62 | return c; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /motif/src/test/java/com/leacox/motif/cases/Animal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case2; 20 | import com.leacox.motif.tuple.Tuple2; 21 | 22 | import com.google.auto.value.AutoValue; 23 | 24 | /** 25 | * @author John Leacox 26 | */ 27 | @AutoValue 28 | public abstract class Animal implements Case2 { 29 | public static Animal create(String name, int numberOfLegs) { 30 | return new AutoValue_Animal(name, numberOfLegs); 31 | } 32 | 33 | abstract String name(); 34 | 35 | abstract int numberOfLegs(); 36 | 37 | @Override 38 | public Tuple2 extract() { 39 | return Tuple2.of(name(), numberOfLegs()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /motif/src/test/java/com/leacox/motif/cases/CaseClassCasesSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import static com.insightfullogic.lambdabehave.Suite.describe; 20 | import static com.leacox.motif.MatchesAny.any; 21 | import static com.leacox.motif.MatchesExact.eq; 22 | import static com.leacox.motif.Motif.match; 23 | import static com.leacox.motif.cases.Case2Cases.case2; 24 | 25 | import com.leacox.motif.caseclass.Case2; 26 | 27 | import com.insightfullogic.lambdabehave.JunitSuiteRunner; 28 | 29 | import org.junit.runner.RunWith; 30 | 31 | /** 32 | * @author John Leacox 33 | */ 34 | 35 | @RunWith(JunitSuiteRunner.class) 36 | public class CaseClassCasesSpec { 37 | { 38 | Case2 cat = Animal.create("Cat", 4); 39 | NotAnimal rock = NotAnimal.create("Rock", 0); 40 | describe( 41 | "the case pattern", it -> { 42 | it.should( 43 | "match cat", expect -> { 44 | String result = match(cat) 45 | .when(case2(NotAnimal.class, eq("Cat"), eq(4))).get(() -> "Nope") 46 | .when(case2(Animal.class, eq("Cat"), eq(4))).get(() -> "Yep") 47 | .getMatch(); 48 | 49 | expect.that(result).is("Yep"); 50 | }); 51 | 52 | it.should( 53 | "match cat and extract name", expect -> { 54 | String result = match(cat) 55 | .when(case2(NotAnimal.class, eq("Cat"), eq(4))).get(() -> "Nope") 56 | .when(case2(Animal.class, any(), eq(4))).get(name -> name) 57 | .getMatch(); 58 | 59 | expect.that(result).is("Cat"); 60 | }); 61 | 62 | it.should( 63 | "match cat and extract legs", expect -> { 64 | String result = match(cat) 65 | .when(case2(NotAnimal.class, eq("Cat"), eq(4))).get(() -> "Nope") 66 | .when(case2(Animal.class, eq("Cat"), any())).get(legs -> legs.toString()) 67 | .getMatch(); 68 | 69 | expect.that(result).is("4"); 70 | }); 71 | 72 | it.should( 73 | "match cat and extract name and legs", expect -> { 74 | String result = match(cat) 75 | .when(case2(NotAnimal.class, eq("Cat"), eq(4))).get(() -> "Nope") 76 | .when(case2(Animal.class, any(), any())).get( 77 | (name, legs) -> "(" + name + ", " + legs + ")") 78 | .getMatch(); 79 | 80 | expect.that(result).is("(Cat, 4)"); 81 | }); 82 | } 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /motif/src/test/java/com/leacox/motif/cases/Consuming.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | /** 20 | * A helper class for testing pattern matching with consumers. 21 | * 22 | * @author John Leacox 23 | */ 24 | class Consuming { 25 | private Object t; 26 | 27 | public Object getConsumed() { 28 | return t; 29 | } 30 | 31 | public void consume(Object t) { 32 | this.t = t; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /motif/src/test/java/com/leacox/motif/cases/NotAnimal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import com.leacox.motif.caseclass.Case2; 20 | import com.leacox.motif.tuple.Tuple2; 21 | 22 | import com.google.auto.value.AutoValue; 23 | 24 | /** 25 | * @author John Leacox 26 | */ 27 | @AutoValue 28 | public abstract class NotAnimal implements Case2 { 29 | 30 | public static NotAnimal create(String notName, int notNumberOfLegs) { 31 | return new AutoValue_NotAnimal(notName, notNumberOfLegs); 32 | } 33 | 34 | public abstract String notName(); 35 | 36 | public abstract int notNumberOfLegs(); 37 | 38 | @Override 39 | public Tuple2 extract() { 40 | return Tuple2.of(notName(), notNumberOfLegs()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /motif/src/test/java/com/leacox/motif/cases/TypeOfCasesSpec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.cases; 18 | 19 | import static com.insightfullogic.lambdabehave.Suite.describe; 20 | import static com.leacox.motif.Motif.match; 21 | import static com.leacox.motif.cases.TypeOfCases.typeOf; 22 | 23 | import com.insightfullogic.lambdabehave.JunitSuiteRunner; 24 | 25 | import org.junit.runner.RunWith; 26 | 27 | import java.time.OffsetDateTime; 28 | import java.time.ZoneOffset; 29 | 30 | /** 31 | * @author John Leacox 32 | */ 33 | @RunWith(JunitSuiteRunner.class) 34 | public class TypeOfCasesSpec { 35 | { 36 | String myString = "string"; 37 | Double pi = 3.14159; 38 | OffsetDateTime currentDateTime = OffsetDateTime.now(ZoneOffset.UTC); 39 | 40 | describe( 41 | "the typeof pattern", it -> { 42 | it.should( 43 | "match String", expect -> { 44 | String result = match(myString) 45 | .when(typeOf(Double.class)).get(Object::toString) 46 | .when(typeOf(OffsetDateTime.class)).get(OffsetDateTime::toString) 47 | .when(typeOf(String.class)).get(s -> s) 48 | .getMatch(); 49 | 50 | expect.that(result).is(myString); 51 | }); 52 | 53 | it.should( 54 | "match OffsetDateTime", expect -> { 55 | String result = match(currentDateTime) 56 | .when(typeOf(Double.class)).get(Object::toString) 57 | .when(typeOf(OffsetDateTime.class)).get(OffsetDateTime::toString) 58 | .when(typeOf(String.class)).get(s -> s) 59 | .getMatch(); 60 | 61 | expect.that(result).is(currentDateTime.toString()); 62 | }); 63 | 64 | it.should( 65 | "match Double", expect -> { 66 | String result = match(pi) 67 | .when(typeOf(Double.class)).get(Object::toString) 68 | .when(typeOf(OffsetDateTime.class)).get(OffsetDateTime::toString) 69 | .when(typeOf(String.class)).get(s -> s) 70 | .getMatch(); 71 | 72 | expect.that(result).is(pi.toString()); 73 | }); 74 | }); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /motif/src/test/java/com/leacox/motif/tuple/Tuple2Spec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 John Leacox 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.leacox.motif.tuple; 18 | 19 | import static com.insightfullogic.lambdabehave.Suite.describe; 20 | 21 | import com.insightfullogic.lambdabehave.JunitSuiteRunner; 22 | 23 | import org.junit.runner.RunWith; 24 | 25 | /** 26 | * @author John Leacox 27 | */ 28 | @RunWith(JunitSuiteRunner.class) 29 | public class Tuple2Spec { 30 | { 31 | describe( 32 | "Tuple2", it -> it.should( 33 | "put tuple values inside () for toString", expect -> { 34 | Tuple2 tuple2 = Tuple2.of("AString", 83); 35 | 36 | expect.that(tuple2.toString()).is(("(AString,83)")); 37 | }) 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | --------------------------------------------------------------------------------