├── .gitignore
├── .github
└── dependabot.yml
├── pom.xml
├── src
├── test
│ └── java
│ │ └── co
│ │ └── nstant
│ │ └── in
│ │ └── pipe
│ │ └── PipeTest.java
└── main
│ └── java
│ └── co
│ └── nstant
│ └── in
│ └── pipe
│ └── Pipe.java
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .settings/
4 | target/
5 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: maven
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "04:00"
8 | open-pull-requests-limit: 10
9 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | co.nstant.in
5 | java-pipe
6 | 1.0.0
7 |
8 |
9 | junit
10 | junit
11 | 4.13.2
12 | test
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/test/java/co/nstant/in/pipe/PipeTest.java:
--------------------------------------------------------------------------------
1 | package co.nstant.in.pipe;
2 |
3 | import static co.nstant.in.pipe.Pipe.apply;
4 | import static org.junit.Assert.assertEquals;
5 |
6 | import org.junit.Test;
7 |
8 | public class PipeTest {
9 |
10 | @Test
11 | public void testPipe() {
12 | assertEquals("11", apply("ab")
13 | .pipe((a) -> a.toUpperCase())
14 | .pipe((a, b) -> a.replace('A', b), '1')
15 | .pipe((a, b, c) -> a.replace(b, c), 'B', '2')
16 | .pipe((a) -> Integer.valueOf(a))
17 | .pipe((a, b, c, d) -> a + b * c - d, 1, 2, 3)
18 | .pipe((a) -> a.toString())
19 | .result());
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Constantin Rack
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # java-pipe
2 |
3 | Implementation of the [Elixir pipe operator](https://elixirschool.com/en/lessons/basics/pipe-operator/) behavior in Java.
4 |
5 | Functions with up to 3 (TriFunction) respectively 4 (QuadriFunction) arguments are supported.
6 |
7 | ## Description
8 |
9 | In [Elixir](https://elixir-lang.org/),
10 | a value can be passed to a function using the pipe operator (`|>`),
11 | where the value is automatically used as first argument of the function.
12 |
13 | While Java 8 has introduced [function composition](https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html) with `.andThen()`, it is not exactly what I was searching for when trying to mimic
14 | Elixir's pipe operator in Java. So I wrote this small class and hope someone finds it useful.
15 |
16 | ## Usage example
17 |
18 | ```java
19 | apply("ab")
20 | .pipe((a) -> a.toUpperCase()) // "AB"
21 | .pipe((a, b) -> a.replace('A', b), '1') // "1B"
22 | .pipe((a, b, c) -> a.replace(b, c), 'B', '2') // "12"
23 | .pipe((a) -> Integer.valueOf(a)) // 12
24 | .pipe((a, b, c, d) -> a + b * c - d, 1, 2, 3) // 11
25 | .pipe((a) -> a.toString()) // "11"
26 | .result()
27 | ```
28 |
--------------------------------------------------------------------------------
/src/main/java/co/nstant/in/pipe/Pipe.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Implementation of the Elixir pipe operator behavior in Java.
3 | *
4 | * Copyright (c) 2017 Constantin Rack
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package co.nstant.in.pipe;
25 |
26 | import java.util.function.BiFunction;
27 | import java.util.function.Function;
28 |
29 | public class Pipe {
30 |
31 | @FunctionalInterface
32 | public interface TriFunction {
33 |
34 | R apply(A a, B b, C c);
35 |
36 | }
37 |
38 | @FunctionalInterface
39 | public interface QuadriFunction {
40 |
41 | R apply(A a, B b, C c, D d);
42 |
43 | }
44 |
45 | public final A a;
46 |
47 | private Pipe(A a) {
48 | this.a = a;
49 | }
50 |
51 | public static Pipe apply(A a) {
52 | return new Pipe(a);
53 | }
54 |
55 | public Pipe pipe(Function f) {
56 | return new Pipe(f.apply(a));
57 | }
58 |
59 | public Pipe pipe(BiFunction f, B b) {
60 | return new Pipe(f.apply(a, b));
61 | }
62 |
63 | public Pipe pipe(TriFunction f, B b, C c) {
64 | return new Pipe(f.apply(a, b, c));
65 | }
66 |
67 | public Pipe pipe(QuadriFunction f, B b, C c, D d) {
68 | return new Pipe(f.apply(a, b, c, d));
69 | }
70 |
71 | public A result() {
72 | return a;
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------