Skip to content

Commit b739ce7

Browse files
authored
Further functional interfaces (#110)
* Fix a warning over generics * Extract IOFunction from test case to be usable elsewhere. Complements IOConsumer * Add IOSupplier to complement IOFunction and IOConsumer
1 parent f77de5c commit b739ce7

4 files changed

Lines changed: 420 additions & 13 deletions

File tree

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.io.function;
19+
20+
import java.io.IOException;
21+
import java.util.Objects;
22+
import java.util.function.Consumer;
23+
import java.util.function.Function;
24+
import java.util.function.Supplier;
25+
26+
/**
27+
* Like {@link Function} but throws {@link IOException}.
28+
*
29+
* @param <T> the type of the input to the operations.
30+
* @param <R> the return type of the operations.
31+
* @since 2.7
32+
*/
33+
@FunctionalInterface
34+
public interface IOFunction<T, R> {
35+
36+
/**
37+
* Applies this function to the given argument.
38+
*
39+
* @param t the function argument
40+
* @return the function result
41+
*
42+
* @throws IOException if the function throws an IOException
43+
*/
44+
R apply(final T t) throws IOException;
45+
46+
/**
47+
* Returns a composed {@link IOFunction} that first applies the {@code before}
48+
* function to its input, and then applies this function to the result.
49+
* If evaluation of either function throws an exception, it is relayed to
50+
* the caller of the composed function.
51+
*
52+
* @param <V> the type of input to the {@code before} function, and to the
53+
* composed function
54+
* @param before the function to apply before this function is applied
55+
* @return a composed function that first applies the {@code before}
56+
* function and then applies this function
57+
* @throws NullPointerException if before is null
58+
*
59+
* @see #andThen(IOFunction)
60+
*/
61+
default <V> IOFunction<V, R> compose(final IOFunction<? super V, ? extends T> before) {
62+
Objects.requireNonNull(before);
63+
return (V v) -> apply(before.apply(v));
64+
}
65+
66+
/**
67+
* Returns a composed {@link IOFunction} that first applies the {@code before}
68+
* function to its input, and then applies this function to the result.
69+
* If evaluation of either function throws an exception, it is relayed to
70+
* the caller of the composed function.
71+
*
72+
* @param <V> the type of input to the {@code before} function, and to the
73+
* composed function
74+
* @param before the function to apply before this function is applied
75+
* @return a composed function that first applies the {@code before}
76+
* function and then applies this function
77+
* @throws NullPointerException if before is null
78+
*
79+
* @see #andThen(IOFunction)
80+
*/
81+
default <V> IOFunction<V, R> compose(final Function<? super V, ? extends T> before) {
82+
Objects.requireNonNull(before);
83+
return (V v) -> apply(before.apply(v));
84+
}
85+
86+
/**
87+
* Returns a composed {@link IOFunction} that first applies the {@code before}
88+
* function to its input, and then applies this function to the result.
89+
* If evaluation of either function throws an exception, it is relayed to
90+
* the caller of the composed function.
91+
*
92+
* @param before the supplier which feeds the application of this function
93+
* @return a composed function that first applies the {@code before}
94+
* function and then applies this function
95+
* @throws NullPointerException if before is null
96+
*
97+
* @see #andThen(IOFunction)
98+
*/
99+
default IOSupplier<R> compose(final IOSupplier<? extends T> before) {
100+
Objects.requireNonNull(before);
101+
return () -> apply(before.get());
102+
}
103+
104+
/**
105+
* Returns a composed {@link IOFunction} that first applies the {@code before}
106+
* function to its input, and then applies this function to the result.
107+
* If evaluation of either function throws an exception, it is relayed to
108+
* the caller of the composed function.
109+
*
110+
* @param before the supplier which feeds the application of this function
111+
* @return a composed function that first applies the {@code before}
112+
* function and then applies this function
113+
* @throws NullPointerException if before is null
114+
*
115+
* @see #andThen(IOFunction)
116+
*/
117+
default IOSupplier<R> compose(final Supplier<? extends T> before) {
118+
Objects.requireNonNull(before);
119+
return () -> apply(before.get());
120+
}
121+
122+
/**
123+
* Returns a composed {@link IOFunction} that first applies this function to
124+
* its input, and then applies the {@code after} function to the result.
125+
* If evaluation of either function throws an exception, it is relayed to
126+
* the caller of the composed function.
127+
*
128+
* @param <V> the type of output of the {@code after} function, and of the
129+
* composed function
130+
* @param after the function to apply after this function is applied
131+
* @return a composed function that first applies this function and then
132+
* applies the {@code after} function
133+
* @throws NullPointerException if after is null
134+
*
135+
* @see #compose(IOFunction)
136+
*/
137+
default <V> IOFunction<T, V> andThen(IOFunction<? super R, ? extends V> after) {
138+
Objects.requireNonNull(after);
139+
return (T t) -> after.apply(apply(t));
140+
}
141+
142+
/**
143+
* Returns a composed {@link IOFunction} that first applies this function to
144+
* its input, and then applies the {@code after} function to the result.
145+
* If evaluation of either function throws an exception, it is relayed to
146+
* the caller of the composed function.
147+
*
148+
* @param <V> the type of output of the {@code after} function, and of the
149+
* composed function
150+
* @param after the function to apply after this function is applied
151+
* @return a composed function that first applies this function and then
152+
* applies the {@code after} function
153+
* @throws NullPointerException if after is null
154+
*
155+
* @see #compose(IOFunction)
156+
*/
157+
default <V> IOFunction<T, V> andThen(Function<? super R, ? extends V> after) {
158+
Objects.requireNonNull(after);
159+
return (T t) -> after.apply(apply(t));
160+
}
161+
162+
/**
163+
* Returns a composed {@link IOFunction} that first applies this function to
164+
* its input, and then applies the {@code after} consumer to the result.
165+
* If evaluation of either function throws an exception, it is relayed to
166+
* the caller of the composed function.
167+
*
168+
* @param after the consumer to apply after this function is applied
169+
* @return a composed function that first applies this function and then
170+
* applies the {@code after} consumer
171+
* @throws NullPointerException if after is null
172+
*
173+
* @see #compose(IOFunction)
174+
*/
175+
default IOConsumer<T> andThen(IOConsumer<? super R> after) {
176+
Objects.requireNonNull(after);
177+
return (T t) -> after.accept(apply(t));
178+
}
179+
180+
/**
181+
* Returns a composed {@link IOFunction} that first applies this function to
182+
* its input, and then applies the {@code after} consumer to the result.
183+
* If evaluation of either function throws an exception, it is relayed to
184+
* the caller of the composed function.
185+
*
186+
* @param after the consumer to apply after this function is applied
187+
* @return a composed function that first applies this function and then
188+
* applies the {@code after} consumer
189+
* @throws NullPointerException if after is null
190+
*
191+
* @see #compose(IOFunction)
192+
*/
193+
default IOConsumer<T> andThen(Consumer<? super R> after) {
194+
Objects.requireNonNull(after);
195+
return (T t) -> after.accept(apply(t));
196+
}
197+
198+
/**
199+
* Returns a {@link IOFunction} that always returns its input argument.
200+
*
201+
* @param <T> the type of the input and output objects to the function
202+
* @return a function that always returns its input argument
203+
*/
204+
static <T> IOFunction<T, T> identity() {
205+
return t -> t;
206+
}
207+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.io.function;
19+
20+
import java.io.IOException;
21+
import java.util.function.Supplier;
22+
23+
/**
24+
* Like {@link Supplier} but throws {@link IOException}.
25+
*
26+
* @param <T> the return type of the operations.
27+
* @since 2.7
28+
*/
29+
@FunctionalInterface
30+
public interface IOSupplier<T> {
31+
32+
/**
33+
* Gets a result.
34+
*
35+
* @return a result
36+
*
37+
* @throws IOException if an IO error occurs whilst supplying the value.
38+
*/
39+
T get() throws IOException;
40+
}

0 commit comments

Comments
 (0)