Skip to content

feat(interop): add Result.fromOptional and Try.fromOptional (#45)#60

Merged
domix merged 1 commit intomainfrom
feature/optional_interop
Mar 5, 2026
Merged

feat(interop): add Result.fromOptional and Try.fromOptional (#45)#60
domix merged 1 commit intomainfrom
feature/optional_interop

Conversation

@domix
Copy link
Owner

@domix domix commented Mar 5, 2026

Bridge java.util.Optional to both Result and Try:

  • Result.fromOptional(Optional<V>)Result<V, NoSuchElementException>
  • Try.fromOptional(Optional<V>, Supplier<Throwable>)Try<V>

Includes null-guard validation and 7 new tests in InteropTest.

Pull Request

📌 Summary

Briefly describe the purpose of this pull request and what problem it solves.

Example: This PR adds a functional implementation of a lazy list, demonstrating deferred computation using Java 17 features.


✅ Checklist

Please check all that apply:

  • I have tested my changes locally
  • I have added unit tests where applicable
  • I have updated documentation where necessary
  • My code follows the project's coding conventions
  • I have linked any related issue(s) below

🔗 Related Issues

Closes #45
Fixes #[issue-number]
(Related but not closing: #[issue-number])


💬 Additional Notes

Any other context, screenshots, design decisions, or points to be reviewed carefully.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added conversion utilities to transform Java Optional instances into Result and Try types, enabling seamless interoperability with automatic error handling for empty Optionals.
  • Tests

    • Added comprehensive test coverage for Optional interoperability with Result and Try, including edge cases such as null handling and lazy evaluation behavior.

  Bridge `java.util.Optional` to both `Result` and `Try`:
  - `Result.fromOptional(Optional<V>)` → `Result<V, NoSuchElementException>`
  - `Try.fromOptional(Optional<V>, Supplier<Throwable>)` → `Try<V>`

  Includes null-guard validation and 7 new tests in `InteropTest`.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

📝 Walkthrough

Walkthrough

Added factory methods to Result and Try classes for converting Java's Optional type. Result.fromOptional converts present/empty Optionals to Ok/Err variants with NoSuchElementException for empty cases. Try.fromOptional accepts a supplier for custom error handling. Comprehensive tests validate both conversions and edge cases.

Changes

Cohort / File(s) Summary
Optional Interop Methods
lib/src/main/java/codes/domix/fun/Result.java, lib/src/main/java/codes/domix/fun/Try.java
Added static factory methods to convert Optional to Result and Try. Result variant maps present→Ok, empty→Err(NoSuchElementException). Try variant maps present→Success, empty→Failure(supplier.get()). Both include null validation.
Optional Interop Tests
lib/src/test/java/codes/domix/fun/InteropTest.java
Added comprehensive test suite covering Result.fromOptional and Try.fromOptional with present/empty states, error type validation, null input handling, lazy evaluation of supplier, and null supplier rejection.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • PR #36: Both PRs add Java Optional interop and modify Result/Try conversion utilities with similar factory method patterns.
  • PR #16: Both PRs introduce Optional/Option interop methods and expand the same core Result.java and Try.java files with conversion utilities.

Poem

🐰 Optional came hopping by,
Said "Convert me, give it a try!"
Result and Try both lent a hand,
Now Optional works across the land! 🎉
From empty to error, present to success,
No more manual wrapping mess!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.46% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding Result.fromOptional and Try.fromOptional methods for Optional interop.
Description check ✅ Passed The description partially follows the template with a summary of changes and linked issue reference, but multiple checklist items are not completed.
Linked Issues check ✅ Passed The PR implements Result.fromOptional and Try.fromOptional as specified in issue #45, with null-guard validation and comprehensive tests. Option interop methods were not included but were noted as proposed in the issue.
Out of Scope Changes check ✅ Passed All changes are in-scope: two new conversion methods in Result and Try classes, supporting imports, and comprehensive test coverage in InteropTest.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/optional_interop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Mar 5, 2026

Overall Project 99.15% 🍏
Files changed 100% 🍏

File Coverage
Try.java 99.32% 🍏
Result.java 98.31% 🍏

@domix
Copy link
Owner Author

domix commented Mar 5, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lib/src/test/java/codes/domix/fun/InteropTest.java (1)

168-178: Add one test for exceptionSupplier returning null.

This is a useful edge case to pin the Line 697 contract in Try.fromOptional.

Proposed test addition
 `@Test`
 void try_fromOptional_nullSupplier_throwsNPE() {
     assertThrows(NullPointerException.class,
         () -> Try.fromOptional(Optional.empty(), null));
 }
+
+@Test
+void try_fromOptional_supplierReturningNull_throwsNPE() {
+    assertThrows(NullPointerException.class,
+        () -> Try.fromOptional(Optional.empty(), () -> null));
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/src/test/java/codes/domix/fun/InteropTest.java` around lines 168 - 178,
Add a test that verifies Try.fromOptional throws a NullPointerException when the
provided exceptionSupplier returns null: create a new test method (e.g.,
try_fromOptional_exceptionSupplierReturningNull_throwsNPE) that calls
Try.fromOptional(Optional.empty(), () -> null) and uses
assertThrows(NullPointerException.class, ...) to assert the behavior; reference
the Try.fromOptional method and the exceptionSupplier lambda in the test so the
edge case at the method's contract is covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/src/test/java/codes/domix/fun/InteropTest.java`:
- Around line 168-178: Add a test that verifies Try.fromOptional throws a
NullPointerException when the provided exceptionSupplier returns null: create a
new test method (e.g.,
try_fromOptional_exceptionSupplierReturningNull_throwsNPE) that calls
Try.fromOptional(Optional.empty(), () -> null) and uses
assertThrows(NullPointerException.class, ...) to assert the behavior; reference
the Try.fromOptional method and the exceptionSupplier lambda in the test so the
edge case at the method's contract is covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a168317-6fab-4535-90a1-822f69c20059

📥 Commits

Reviewing files that changed from the base of the PR and between b5a3cf4 and e70653e.

📒 Files selected for processing (3)
  • lib/src/main/java/codes/domix/fun/Result.java
  • lib/src/main/java/codes/domix/fun/Try.java
  • lib/src/test/java/codes/domix/fun/InteropTest.java

@domix domix merged commit e1e7b1c into main Mar 5, 2026
4 checks passed
@domix domix deleted the feature/optional_interop branch March 5, 2026 05:19
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

Overall Project 99.15% 🍏
Files changed 100% 🍏

File Coverage
Try.java 99.32% 🍏
Result.java 98.31% 🍏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add interop with java.util.Optional

1 participant