Skip to content

pwall567/kjson-optional

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kjson-optional

Build Status License: MIT Kotlin Maven Central

Optional property for kjson.

IMPORTANT NOTE

There is a bug in the Kotlin reflection subsystem relating to value classes that prevents this library working as intended.

The current version (1.1) uses a regular class instead of a value class, and will therefore not be as efficient as planned. A new version using a value class will be released as soon as the issue is resolved.

Background

When deserializing JSON objects, the kjson library will use the default value in the constructor for any missing properties. The convention is to use null as this default, but this makes it difficult to distinguish between a missing property and one that has been set intentionally to null.

The kjson-optional library provides an Opt class which, when used in conjunction with the appropriate deserialization functions, will provide the ability to determine whether a property was omitted or was supplied with the value null.

Quick Start

A good example of an optional property is the middle name of a name class:

data class PersonName(
    val firstName: String,
    val middleName: Opt<String> = Opt.unset(),
    val surname: String,
)

Then, to access the middleName:

    val displayName = buildString {
        append(firstName)
        append(' ')
        if (middleName.isSet) {
            append(middleName.value)
            append(' ')
        }
        append(surname)
    }

Value Class

Opt is a value class, which means that in many cases the compiler will optimise away the instantiation of a separate "holder" class. The use of Opt will incur some overhead compared to the use of a raw type, but when used as described above, it will not lead to the creation of a large number of small objects, with the associated garbage collection cost.

Naming

The name Opt was chosen because a single data class is likely to contain several optional fields, and a long name would be very obtrusive. The package name io.kjson.optional provides a bit more explanation of the function of the class.

The java.lang.Optional class was considered for this use but ruled out because it does not allow null values, and because it would not allow the use of a value class.

Reference

Creation

To construct an Opt:

    val optString = Opt.of("A string")

or:

    val optString = Opt.unset<String>()

Both of these will construct an Opt<String>.

To construct an Opt from a possibly-null value:

    val optString = Opt.ofNullable(nullableString)

The Opt will be unset if the parameter was null.

In all cases the Opt will be immutable.

Access

To get the value:

    val str = optString.value

str will contain the value as a String; if the Opt was unset a NotSetException (a derived class of IllegalStateException) will be thrown.

To test whether the value is set:

    if (optString.isSet) {
        // use optString.value
        println(optString.value)
    }

To test if the value is unset:

    if (optString.isUnset) {
        // do NOT use optString.value
        println("Value is not set")
    }

To get the value, or null if it was unset:

    val str = optString.orNull

In this case, str will be of type String?.

To get the value, or some other value if it was unset:

    val str = optString.orElse { "default" }

This can be used to throw an alternative exception type in place of NotSetException:

    val str = optString.orElse { throw StringMissingException() }

There is also a convenience function:

    optString.ifSet { println(it) }

The lambda will be executed only if the value is set, and the value will be passed in as the parameter.

Dependency Specification

The latest version of the library is 1.1, and it may be obtained from the Maven Central repository.

Maven

    <dependency>
      <groupId>io.kjson</groupId>
      <artifactId>kjson-optional</artifactId>
      <version>1.1</version>
    </dependency>

Gradle

    implementation "io.kjson:kjson-optional:1.1"

Gradle (kts)

    implementation("io.kjson:kjson-optional:1.1")

Peter Wall

2023-04-11

About

Optional property for kjson

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages