Skip to content

Commit a4ec388

Browse files
committed
Add FailableByteConsumer
1 parent 1852dee commit a4ec388

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ The <action> type attribute can be add,update,fix,remove.
8585
<action type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.lang3.time.DateUtils.toOffsetDateTime(Date[, TimeZone]).</action>
8686
<action type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.lang3.time.DateUtils.toZonedDateTime(Date[, TimeZone]).</action>
8787
<action type="add" dev="ggregory" due-to="Gary Gregory">Add ByteConsumer.</action>
88+
<action type="add" dev="ggregory" due-to="Gary Gregory">Add FailableByteConsumer.</action>
8889
<!-- UPDATE -->
8990
<action type="update" dev="ggregory" due-to="Gary Gregory">[test] Bump org.apache.commons:commons-text from 1.13.1 to 1.14.0.</action>
9091
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 85 to 87.</action>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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+
* https://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.lang3.function;
19+
20+
import java.util.Objects;
21+
import java.util.function.IntConsumer;
22+
23+
/**
24+
* A functional interface like {@link ByteConsumer} that declares a {@link Throwable}.
25+
*
26+
* @param <E> The kind of thrown exception or error.
27+
* @since 3.11
28+
*/
29+
@FunctionalInterface
30+
public interface FailableByteConsumer<E extends Throwable> {
31+
32+
/** NOP singleton */
33+
@SuppressWarnings("rawtypes")
34+
FailableByteConsumer NOP = t -> { /* NOP */ };
35+
36+
/**
37+
* Gets the NOP singleton.
38+
*
39+
* @param <E> The kind of thrown exception or error.
40+
* @return The NOP singleton.
41+
*/
42+
@SuppressWarnings("unchecked")
43+
static <E extends Throwable> FailableByteConsumer<E> nop() {
44+
return NOP;
45+
}
46+
47+
/**
48+
* Accepts the given arguments.
49+
*
50+
* @param value the parameter for the consumable to accept
51+
* @throws E Thrown when the consumer fails.
52+
*/
53+
void accept(byte value) throws E;
54+
55+
/**
56+
* Returns a composed {@link FailableByteConsumer} like {@link IntConsumer#andThen(IntConsumer)}.
57+
*
58+
* @param after the operation to perform after this one.
59+
* @return a composed {@link FailableByteConsumer} like {@link IntConsumer#andThen(IntConsumer)}.
60+
* @throws NullPointerException if {@code after} is null
61+
*/
62+
default FailableByteConsumer<E> andThen(final FailableByteConsumer<E> after) {
63+
Objects.requireNonNull(after);
64+
return (final byte t) -> {
65+
accept(t);
66+
after.accept(t);
67+
};
68+
}
69+
70+
}

src/test/java/org/apache/commons/lang3/function/FailableFunctionsTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,24 @@ void testBiPredicateOr() throws Throwable {
761761
() -> assertTrue(FailableBiPredicate.truePredicate().or(null).test(null, null)));
762762
}
763763

764+
@Test
765+
void testByteConsumerAndThen() throws Throwable {
766+
final Testable<?, ?> testable = new Testable<>(null);
767+
final FailableByteConsumer<Throwable> failing = t -> {
768+
testable.setThrowable(ERROR);
769+
testable.test();
770+
};
771+
final FailableByteConsumer<Throwable> nop = FailableByteConsumer.nop();
772+
Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.andThen(failing).accept((byte) 0));
773+
assertSame(ERROR, e);
774+
e = assertThrows(OutOfMemoryError.class, () -> failing.andThen(nop).accept((byte) 0));
775+
assertSame(ERROR, e);
776+
// Does not throw
777+
nop.andThen(nop);
778+
// Documented in Javadoc edge-case.
779+
assertNullPointerException(() -> failing.andThen(null));
780+
}
781+
764782
@Test
765783
void testCallable() {
766784
FailureOnOddInvocations.invocations = 0;
@@ -1629,6 +1647,37 @@ public boolean getAsBoolean() throws Throwable {
16291647
}.getAsBoolean());
16301648
}
16311649

1650+
/**
1651+
* Tests that our failable interface is properly defined to throw any exception using String and IOExceptions as
1652+
* generic test types.
1653+
*/
1654+
@Test
1655+
void testThrows_FailableByteConsumer_IOException() {
1656+
assertThrows(IOException.class, () -> new FailableByteConsumer<IOException>() {
1657+
1658+
@Override
1659+
public void accept(final byte value) throws IOException {
1660+
throw new IOException("test");
1661+
}
1662+
}.accept((byte) 0));
1663+
}
1664+
1665+
/**
1666+
* Tests that our failable interface is properly defined to throw any exception using the top level generic types
1667+
* Object and Throwable.
1668+
*/
1669+
@Test
1670+
void testThrows_FailableByteConsumer_Throwable() {
1671+
assertThrows(IOException.class, () -> new FailableByteConsumer<Throwable>() {
1672+
1673+
@Override
1674+
public void accept(final byte value) throws Throwable {
1675+
throw new IOException("test");
1676+
1677+
}
1678+
}.accept((byte) 0));
1679+
}
1680+
16321681
/**
16331682
* Tests that our failable interface is properly defined to throw any exception using the top level generic types
16341683
* Object and Throwable.

0 commit comments

Comments
 (0)