Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/foxcapades/lib-java-opt

Extensible alternative to Java's built-in option type.
https://github.com/foxcapades/lib-java-opt

java lib library option optional options

Last synced: 5 days ago
JSON representation

Extensible alternative to Java's built-in option type.

Awesome Lists containing this project

README

        

= Extensible Java Options
:dep-version: 1.1.0

image:https://img.shields.io/badge/Java-16-ff69b4[]
image:https://img.shields.io/badge/license-MIT-brightgreen[]
image:https://img.shields.io/badge/docs-javadoc-blue[link="https://foxcapades.github.io/lib-java-opt/foxcapades.lib.opt/module-summary.html"]
image:https://img.shields.io/maven-central/v/io.foxcapades.lib/opt[link="https://search.maven.org/artifact/io.foxcapades.lib/opt/{dep-version}/jar"]

Provides an alternative, extensible alternative to Java's built-in `Optional`
type.

Additionally, this library adds a "3 state" option type for wrapping values that
could be present, absent, or `null`. (The built-in Java option does not support
wrapping `null`).

== Features

The root of this library is the `Option` interface which is subclassed by the
interfaces `NullableOption` and `NonNullOption`.

=== `Option`

`Option` is the base interface for the library and includes most if not all the
features of the built-in `Optional` type.

=== `NonNullOption`

`NonNullOption` extends the `Option` interface and is a more of a direct mirror
of the built-in `Optional`. Implementations of this interface do not allow
wrapping `null` and translate `null` to "empty".

=== `NullableOption`

The `NullableOption` extends the `Option` interface and provides additional
functionality for dealing with `null` values.

== Usage

The primary entry point for this library is the included `Opt` factory which is
used to construct the different `Option` types. This factory includes a
standard configuration, but may be overridden with an alternate implementation.

.Creating a `NullableOption`
[source, java]
----
// Empty nullable option
var opt1 = Opt.nullable();

// Nullable option wrapping null
var opt2 = Opt.nullable(null);

// Nullable option wrapping a non-null value
var opt3 = Opt.nullable("hello");
----

.Creating a `NonNullOption`
[source, java]
----
// Empty option
var opt1 = Opt.nonNull();

// Empty option
var opt2 = Opt.nonNullOfNullable(null);

// Non-empty option
var opt3 = Opt.nonNull(1234);

// Non-empty option
var opt4 = Opt.nonNullOfNullable("goodbye");

// Throws NullPointerException
var opt5 = Opt.nonNull(null);
----

=== Dependency Config

.Maven
[source, xml, subs="+attributes"]
----

io.foxcapades.lib
opt
{dep-version}

----

.Gradle Groovy
[source, groovy, subs="+attributes"]
----
implementation 'io.foxcapades.lib:opt:{dep-version}'
----

.Gradle Kotlin
[source, kotlin, subs="+attributes"]
----
implementation("io.foxcapades.lib:opt:{dep-version}")
----

=== Factory Building Custom Implementations

Using custom implementations of option types may be used with the option factory
`Opt` by extending the `Opt` class and setting it as the default/singleton
instance.

.Overriding to provide a custom null option type.
[source, java]
----
public class MyOpt extends Opt {
@Override
public NullableOption newNullable() {
return new MyOption<>();
}
}

...

Opt.setStandardInstance(new MyOpt());

assert Opt.nullable() instanceof MyOpt;
----

== Reasoning

In practice, especially when dealing with external APIs, I have personally found
myself frustrated with the `Optional` type's lack of features, inability to wrap
`null`, and the fact that the type is `final` so desired features could not even
be added.

== Why would you want to wrap `null`?

Ideally, you wouldn't. However, many APIs differentiate between a property
being absent, vs being present and null, vs being present and not-null. One
popular example of such an API would be JSON patch.