You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2024/11/06 19:36:12 UTC

(commons-io) branch master updated: Add IOIntConsumer

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git


The following commit(s) were added to refs/heads/master by this push:
     new e21cd026e Add IOIntConsumer
e21cd026e is described below

commit e21cd026e0aa86665fc0e0f0bed5da676c70fe85
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Wed Nov 6 14:36:05 2024 -0500

    Add IOIntConsumer
---
 src/changes/changes.xml                            |  1 +
 .../apache/commons/io/function/IOIntConsumer.java  | 82 ++++++++++++++++++++++
 .../org/apache/commons/io/function/Uncheck.java    | 16 +++++
 .../commons/io/function/IOIntConsumerTest.java     | 78 ++++++++++++++++++++
 .../apache/commons/io/function/TestConstants.java  |  2 +
 .../org/apache/commons/io/function/TestUtils.java  |  4 ++
 6 files changed, 183 insertions(+)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 4b6961725..93cbfceae 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -64,6 +64,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action dev="ggregory" type="add"                due-to="Gary Gregory">Add ValidatingObjectInputStream.ObjectStreamClassPredicate to allow configuration reuse.</action>
       <action dev="ggregory" type="add"                due-to="Gary Gregory">Add RandomAccessFileMode.accept(Path, IOConsumer&lt;RandomAccessFile&gt;).</action>
       <action dev="ggregory" type="add"                due-to="Gary Gregory">Add RandomAccessFileMode.apply(Path, IOFunction&lt;RandomAccessFile&gt;, T).</action>
+      <action dev="ggregory" type="add"                due-to="Gary Gregory">Add IOIntConsumer.</action>
       <!-- UPDATE -->
       <action dev="ggregory" type="update"             due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 74 to 78 #670, #676, #679, #688.</action>
       <action dev="ggregory" type="update"             due-to="Gary Gregory">Bump commons.bytebuddy.version from 1.15.1 to 1.15.8 #672, #673, #685, #686, #694, #696.</action>
diff --git a/src/main/java/org/apache/commons/io/function/IOIntConsumer.java b/src/main/java/org/apache/commons/io/function/IOIntConsumer.java
new file mode 100644
index 000000000..fb5f29134
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/function/IOIntConsumer.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.io.function;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.IntConsumer;
+
+/**
+ * Like {@link IntConsumer} but throws {@link IOException}.
+ *
+ * @since 2.18.0
+ */
+@FunctionalInterface
+public interface IOIntConsumer {
+
+    /**
+     * The constant no-op consumer.
+     */
+    IOIntConsumer NOOP = i -> {/* noop */};
+
+    /**
+     * Performs this operation on the given argument.
+     *
+     * @param value the input argument
+     * @throws IOException if an I/O error occurs.
+     */
+    void accept(int value) throws IOException;
+
+    /**
+     * Returns a composed {@code IOIntConsumer} that performs, in sequence, this operation followed by the {@code after} operation. If performing either
+     * operation throws an exception, it is relayed to the caller of the composed operation. If performing this operation throws an exception, the {@code after}
+     * operation will not be performed.
+     *
+     * @param after the operation to perform after this operation
+     * @return a composed {@code IOIntConsumer} that performs in sequence this operation followed by the {@code after} operation
+     * @throws NullPointerException if {@code after} is null
+     */
+    default IOIntConsumer andThen(final IOIntConsumer after) {
+        Objects.requireNonNull(after);
+        return (final int i) -> {
+            accept(i);
+            after.accept(i);
+        };
+    }
+
+    /**
+     * Creates a {@link Consumer} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}.
+     *
+     * @return an UncheckedIOException IntConsumer.
+     */
+    default Consumer<Integer> asConsumer() {
+        return i -> Uncheck.accept(this, i);
+    }
+
+    /**
+     * Creates an {@link IntConsumer} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}.
+     *
+     * @return an UncheckedIOException IntConsumer.
+     */
+    default IntConsumer asIntConsumer() {
+        return i -> Uncheck.accept(this, i);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/io/function/Uncheck.java b/src/main/java/org/apache/commons/io/function/Uncheck.java
index 3e4010431..f24504256 100644
--- a/src/main/java/org/apache/commons/io/function/Uncheck.java
+++ b/src/main/java/org/apache/commons/io/function/Uncheck.java
@@ -62,6 +62,22 @@ public final class Uncheck {
         }
     }
 
+    /**
+     * Accepts an IO consumer with the given argument.
+     *
+     * @param i the input argument.
+     * @param consumer Consumes the value.
+     * @throws UncheckedIOException if an I/O error occurs.
+     * @since 2.18.0
+     */
+    public static void accept(final IOIntConsumer consumer, final int i) {
+        try {
+            consumer.accept(i);
+        } catch (final IOException e) {
+            throw wrap(e);
+        }
+    }
+
     /**
      * Accepts an IO consumer with the given arguments.
      *
diff --git a/src/test/java/org/apache/commons/io/function/IOIntConsumerTest.java b/src/test/java/org/apache/commons/io/function/IOIntConsumerTest.java
new file mode 100644
index 000000000..7b8611166
--- /dev/null
+++ b/src/test/java/org/apache/commons/io/function/IOIntConsumerTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.io.function;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link IOIntConsumer}.
+ */
+public class IOIntConsumerTest {
+
+    @Test
+    void testAccept() throws IOException {
+        assertDoesNotThrow(() -> IOIntConsumer.NOOP.accept(0));
+        assertDoesNotThrow(() -> IOIntConsumer.NOOP.accept('.'));
+        final AtomicReference<String> ref = new AtomicReference<>();
+        final IOIntConsumer consumer = s -> ref.set(s + "-");
+        consumer.accept(65);
+        assertEquals(65 + "-", ref.get());
+    }
+
+    @Test
+    void testAndThen() throws IOException {
+        final AtomicReference<String> ref = new AtomicReference<>();
+        final IOIntConsumer consumer1 = s -> ref.set(s + "-");
+        final IOIntConsumer consumer2 = s -> ref.set(ref.get() + "=" + s);
+        consumer1.andThen(consumer2).accept(66);
+        assertEquals(66 + "-=" + 66, ref.get());
+    }
+
+    @Test
+    void testAsConsumer() {
+        assertThrows(UncheckedIOException.class, () -> Optional.of(65).ifPresent(TestUtils.throwingIOIntConsumer().asConsumer()));
+        final AtomicReference<String> ref = new AtomicReference<>();
+        final IOIntConsumer consumer1 = s -> ref.set(s + "A");
+        Optional.of(2).ifPresent(consumer1.asConsumer());
+        assertEquals("2A", ref.get());
+    }
+
+    @Test
+    void testasIntConsumer() {
+        final AtomicReference<String> ref = new AtomicReference<>();
+        final IOIntConsumer consumer1 = s -> ref.set(s + "A");
+        consumer1.asIntConsumer().accept(2);
+        assertEquals("2A", ref.get());
+    }
+
+    @Test
+    void testNOOP() {
+        // nothing happens:
+        assertDoesNotThrow(() -> IOIntConsumer.NOOP.accept(0));
+    }
+
+}
diff --git a/src/test/java/org/apache/commons/io/function/TestConstants.java b/src/test/java/org/apache/commons/io/function/TestConstants.java
index be4eb9d0e..803dd4b38 100644
--- a/src/test/java/org/apache/commons/io/function/TestConstants.java
+++ b/src/test/java/org/apache/commons/io/function/TestConstants.java
@@ -42,6 +42,8 @@ final class TestConstants {
 
     static IOConsumer<Object> THROWING_IO_CONSUMER = t -> throwIOException();
 
+    static IOIntConsumer THROWING_IO_INT_CONSUMER = t -> throwIOException();
+
     static IOFunction<Object, Object> THROWING_IO_FUNCTION = t -> throwIOException();
 
     static IOIntSupplier THROWING_IO_INT_SUPPLIER = TestConstants::throwIOException;
diff --git a/src/test/java/org/apache/commons/io/function/TestUtils.java b/src/test/java/org/apache/commons/io/function/TestUtils.java
index d5d7fcdc0..f656f65d4 100644
--- a/src/test/java/org/apache/commons/io/function/TestUtils.java
+++ b/src/test/java/org/apache/commons/io/function/TestUtils.java
@@ -94,6 +94,10 @@ final class TestUtils {
         return (IOFunction<T, U>) TestConstants.THROWING_IO_FUNCTION;
     }
 
+    static IOIntConsumer throwingIOIntConsumer() {
+        return TestConstants.THROWING_IO_INT_CONSUMER;
+    }
+
     @SuppressWarnings("unchecked")
     static <T> IOPredicate<T> throwingIOPredicate() {
         return (IOPredicate<T>) TestConstants.THROWING_IO_PREDICATE;