diff --git a/build.gradle b/build.gradle index 7b81067..f29ea3a 100644 --- a/build.gradle +++ b/build.gradle @@ -37,14 +37,14 @@ compileTestKotlin { } dokka { - outputFormat = 'javadoc' + outputFormat = 'html' outputDirectory = "$buildDir/docs" } -task javadocJar(type: Jar, dependsOn: dokka) { +task kdocJar(type: Jar, dependsOn: dokka) { group = LifecycleBasePlugin.BUILD_GROUP - description = 'Assembles a jar archive containing the Javadoc API documentation.' - classifier = 'javadoc' + description = 'Assembles a jar archive containing the KDoc API documentation.' + classifier = 'kdoc' from dokka.outputDirectory } @@ -59,7 +59,7 @@ publishing { publications { mavenJava(MavenPublication) { from components.java - artifact javadocJar + artifact kdocJar artifact sourcesJar } } diff --git a/src/main/kotlin/com/mikebull94/result/And.kt b/src/main/kotlin/com/mikebull94/result/And.kt index d0f5613..cd80e59 100644 --- a/src/main/kotlin/com/mikebull94/result/And.kt +++ b/src/main/kotlin/com/mikebull94/result/And.kt @@ -1,7 +1,10 @@ package com.mikebull94.result /** - * Rust: [Result.and](https://doc.rust-lang.org/std/result/enum.Result.html#method.and) + * - Rust: [Result.and](https://doc.rust-lang.org/std/result/enum.Result.html#method.and) + * + * @param result The [Result] to return if [Ok]. + * @return The [result] if [Ok], otherwise [err]. */ infix fun Result.and(result: Result): Result { return when (this) { @@ -13,6 +16,9 @@ infix fun Result.and(result: Result): Result { /** * - Elm: [Result.andThen](http://package.elm-lang.org/packages/elm-lang/core/latest/Result#andThen) * - Rust: [Result.and_then](https://doc.rust-lang.org/std/result/enum.Result.html#method.and_then) + * + * @param transform The transformation to apply to the [value][Ok.value]. + * @return The [transformed][transform] [Result] if [Ok], otherwise [err]. */ infix inline fun Result.andThen(transform: (V) -> Result): Result { return when (this) { diff --git a/src/main/kotlin/com/mikebull94/result/Get.kt b/src/main/kotlin/com/mikebull94/result/Get.kt index 8f7146b..4212afd 100644 --- a/src/main/kotlin/com/mikebull94/result/Get.kt +++ b/src/main/kotlin/com/mikebull94/result/Get.kt @@ -3,6 +3,8 @@ package com.mikebull94.result /** * - Elm: [Result.toMaybe](http://package.elm-lang.org/packages/elm-lang/core/latest/Result#toMaybe) * - Rust: [Result.ok](https://doc.rust-lang.org/std/result/enum.Result.html#method.ok) + * + * @return The [value][Ok.value] if [Ok], otherwise `null`. */ fun Result.get(): V? { return when (this) { @@ -13,6 +15,8 @@ fun Result.get(): V? { /** * - Rust: [Result.err](https://doc.rust-lang.org/std/result/enum.Result.html#method.err) + * + * @return The [error][Error.error] if [Error], otherwise `null`. */ fun Result.getError(): E? { return when (this) { @@ -25,6 +29,9 @@ fun Result.getError(): E? { * - Elm: [Result.withDefault](http://package.elm-lang.org/packages/elm-lang/core/latest/Result#withDefault) * - Haskell: [Result.fromLeft](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:fromLeft) * - Rust: [Result.unwrap_or](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or) + * + * @param default The value to return if [Error]. + * @return The [value][Ok.value] if [Ok], otherwise [default]. */ infix fun Result.getOr(default: V): V { return when (this) { @@ -35,6 +42,9 @@ infix fun Result.getOr(default: V): V { /** * - Haskell: [Result.fromRight](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:fromRight) + * + * @param default The error to return if [Ok]. + * @return The [error][Error.error] if [Error], otherwise [default]. */ infix fun Result.getErrorOr(default: E): E { return when (this) { @@ -46,6 +56,9 @@ infix fun Result.getErrorOr(default: E): E { /** * - Elm: [Result.extract](http://package.elm-lang.org/packages/circuithub/elm-result-extra/1.4.0/Result-Extra#extract) * - Rust: [Result.unwrap_or_else](https://doc.rust-lang.org/src/core/result.rs.html#735-740) + * + * @param transform The transformation to apply to the [error][Error.error]. + * @return The [value][Ok.value] if [Ok], otherwise the [transformed][transform] [error][Error.error]. */ infix inline fun Result.getOrElse(transform: (E) -> V): V { return when (this) { diff --git a/src/main/kotlin/com/mikebull94/result/Iterable.kt b/src/main/kotlin/com/mikebull94/result/Iterable.kt index 179c0cb..739f4ef 100644 --- a/src/main/kotlin/com/mikebull94/result/Iterable.kt +++ b/src/main/kotlin/com/mikebull94/result/Iterable.kt @@ -1,5 +1,12 @@ package com.mikebull94.result +/** + * Accumulates value starting with [initial] value and applying [operation] from left to right to + * current accumulator value and each element. + * + * @param initial The value to start with. + * @param operation The operation to apply to each element and current accumulator value. + */ inline fun Iterable.fold( initial: R, operation: (acc: R, T) -> Result @@ -20,6 +27,13 @@ inline fun Iterable.fold( return ok(accumulator) } +/** + * Accumulates value starting with [initial] value and applying [operation] from right to left to + * each element and current accumulator value. + * + * @param initial The value to start with. + * @param operation The operation to apply to each element and current accumulator value. + */ inline fun List.foldRight( initial: R, operation: (T, acc: R) -> Result @@ -44,12 +58,21 @@ inline fun List.foldRight( } /** + * Combine a vararg of [Results][Result] into a single [Result] (holding a [List]). + * * - Elm: [Result.Extra.combine](http://package.elm-lang.org/packages/circuithub/elm-result-extra/1.4.0/Result-Extra#combine) + * + * @param results The [Results][Result] to combine. + * @return The combined [Result]. */ fun combine(vararg results: Result) = results.asIterable().combine() /** + * Combine an [Iterable] of [Results][Result] into a single [Result] (holding a [List]). + * * - Elm: [Result.Extra.combine](http://package.elm-lang.org/packages/circuithub/elm-result-extra/1.4.0/Result-Extra#combine) + * + * @return The combined [Result]. */ fun Iterable>.combine(): Result, E> { return ok(map { @@ -61,36 +84,73 @@ fun Iterable>.combine(): Result, E> { } /** + * Extracts from a vararg of [Results][Result] all the [Ok] elements. All the [Ok] elements are + * extracted in order. + * * - Haskell: [Data.Either.lefts](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:lefts) + * + * @param results The [Results][Result] from which to extract [Ok] elements. + * @return The extracted [Ok] elements. */ fun getAll(vararg results: Result) = results.asIterable().getAll() /** + * Extracts from an [Iterable] of [Results][Result] all the [Ok] elements. All the [Ok] elements + * are extracted in order. + * * - Haskell: [Data.Either.lefts](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:lefts) + * + * @return The extracted [Ok] elements. */ fun Iterable>.getAll(): List { return filter { it is Ok }.map { (it as Ok).value } } /** + * Extracts from a vararg of [Results][Result] all the [Error] elements. All the [Error] elements + * are extracted in order. + * * - Haskell: [Data.Either.rights](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:rights) + * + * @param results The [Results][Result] from which to extract [Error] elements. + * @return The extracted [Error] elements. */ fun getAllErrors(vararg results: Result) = results.asIterable().getAllErrors() /** + * Extracts from an [Iterable] of [Results][Result] all the [Error] elements. All the [Error] + * elements are extracted in order. + * * - Haskell: [Data.Either.rights](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:rights) + * + * @return The extracted [Error] elements. */ fun Iterable>.getAllErrors(): List { return filter { it is Error }.map { (it as Error).error } } /** + * Partitions a vararg of [Results][Result] into a [Pair] of [Lists][List]. All the [Ok] elements + * are extracted, in order, to the [first][Pair.first] value. Similarly the [Error] elements are + * extracted to the [Pair.second] value. + * * - Haskell: [Data.Either.partitionEithers](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:partitionEithers) + * + * @param results The [Results][Result] to partition. + * @return A [Pair] of [Lists][List] where the [first][Pair.first] value + * contains the [Ok] elements and the [second][Pair.second] value contains the [Error] elements. */ fun partition(vararg results: Result) = results.asIterable().partition() /** + * Partitions an [Iterable] of [Results][Result] into a [Pair] of [Lists][List]. All the [Ok] + * elements are extracted, in order, to the [first][Pair.first] value. Similarly the [Error] + * elements are extracted to the [Pair.second] value. + * * - Haskell: [Data.Either.partitionEithers](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:partitionEithers) + * + * @return A [Pair] of [Lists][List] where the [first][Pair.first] value + * contains the [Ok] elements and the [second][Pair.second] value contains the [Error] elements. */ fun Iterable>.partition(): Pair, List> { val values = mutableListOf() diff --git a/src/main/kotlin/com/mikebull94/result/Map.kt b/src/main/kotlin/com/mikebull94/result/Map.kt index 5042639..553c46e 100644 --- a/src/main/kotlin/com/mikebull94/result/Map.kt +++ b/src/main/kotlin/com/mikebull94/result/Map.kt @@ -1,9 +1,15 @@ package com.mikebull94.result /** + * Maps a [Result][Result] to [Result][Result] by applying a function to a contained + * [Ok] value, leaving an [Error] value untouched. + * * - Elm: [Result.map](http://package.elm-lang.org/packages/elm-lang/core/latest/Result#map) * - Haskell: [Data.Bifunctor.first](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bifunctor.html#v:first) * - Rust: [Result.map](https://doc.rust-lang.org/std/result/enum.Result.html#method.map) + * + * @param transform The transformation to apply to the [value][Ok.value] + * @return The [transformed][transform] [Result] if [Ok], otherwise [err]. */ infix inline fun Result.map(transform: (V) -> U): Result { return when (this) { @@ -13,9 +19,15 @@ infix inline fun Result.map(transform: (V) -> U): Result { } /** + * Maps a [Result][Result] to [Result][Result] by applying a function to a contained + * [Error] value, leaving an [Ok] value untouched. + * * - Elm: [Result.mapError](http://package.elm-lang.org/packages/elm-lang/core/latest/Result#mapError) * - Haskell: [Data.Bifunctor.right](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bifunctor.html#v:second) * - Rust: [Result.map_err](https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err) + * + * @param transform The transformation to apply to the [error][Error.error]. + * @return The [value][Ok.value] if [Ok], otherwise the [transformed][transform] [Error]. */ infix inline fun Result.mapError(transform: (E) -> F): Result { return when (this) { @@ -25,8 +37,16 @@ infix inline fun Result.mapError(transform: (E) -> F): Result][Result] to `U` by applying either the [success] function if the [Result] + * is [Ok] or the [failure] function if the [Result] is an [Error]. Both of these functions must + * return the same type (`U`). + * * - Elm: [Result.Extra.mapBoth](http://package.elm-lang.org/packages/circuithub/elm-result-extra/1.4.0/Result-Extra#mapBoth) * - Haskell: [Data.Either.either](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:either) + * + * @param success The function to apply to `V` if [Ok]. + * @param failure The function to apply to `E` if [Error]. + * @return The mapped value. */ inline fun Result.mapBoth( success: (V) -> U, @@ -40,12 +60,19 @@ inline fun Result.mapBoth( // TODO: better name? /** + * Map a [Result][Result] to [Result][Result] by applying either the [success] function + * if the [Result] is [Ok] or the [failure] function if the [Result] is an [Error]. + * * - Haskell: [Data.Bifunctor.Bimap](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bifunctor.html#v:bimap) + * + * @param success The function to apply to `V` if [Ok]. + * @param failure The function to apply to `E` if [Error]. + * @return The mapped [Result]. */ -inline fun Result.mapEither( - success: (V1) -> V2, - failure: (E1) -> E2 -): Result { +inline fun Result.mapEither( + success: (V) -> U, + failure: (E) -> F +): Result { return when (this) { is Ok -> ok(success(value)) is Error -> err(failure(error)) diff --git a/src/main/kotlin/com/mikebull94/result/On.kt b/src/main/kotlin/com/mikebull94/result/On.kt index 5042111..c99b281 100644 --- a/src/main/kotlin/com/mikebull94/result/On.kt +++ b/src/main/kotlin/com/mikebull94/result/On.kt @@ -1,4 +1,13 @@ package com.mikebull94.result +/** + * Calls a [callback] if the [Result] is [Ok]. + * @param callback The function to call. + */ fun Result.onSuccess(callback: (V) -> Unit) = mapBoth(callback, {}) + +/** + * Calls a [callback] if the [Result] is [Error]. + * @param callback The function to call. + */ fun Result.onFailure(callback: (E) -> Unit) = mapBoth({}, callback) diff --git a/src/main/kotlin/com/mikebull94/result/Or.kt b/src/main/kotlin/com/mikebull94/result/Or.kt index b929da3..aab6baf 100644 --- a/src/main/kotlin/com/mikebull94/result/Or.kt +++ b/src/main/kotlin/com/mikebull94/result/Or.kt @@ -2,6 +2,9 @@ package com.mikebull94.result /** * - Rust: [Result.or](https://doc.rust-lang.org/std/result/enum.Result.html#method.or) + * + * @param result The [Result] to return if [Error]. + * @return The [result] if [Error], otherwise [ok]. */ infix fun Result.or(result: Result): Result { return when (this) { @@ -12,6 +15,9 @@ infix fun Result.or(result: Result): Result { /** * - Rust: [Result.or_else](https://doc.rust-lang.org/std/result/enum.Result.html#method.or_else) + * + * @param transform The transformation to apply to the [error][Error.error]. + * @return The [transformed][transform] [Result] if [Error], otherwise [ok]. */ infix inline fun Result.orElse(transform: (E) -> Result): Result { return when (this) { diff --git a/src/main/kotlin/com/mikebull94/result/Result.kt b/src/main/kotlin/com/mikebull94/result/Result.kt index 1733d46..ac3d972 100644 --- a/src/main/kotlin/com/mikebull94/result/Result.kt +++ b/src/main/kotlin/com/mikebull94/result/Result.kt @@ -1,6 +1,8 @@ package com.mikebull94.result /** + * [Result] is a type that represents either success ([Ok]) or failure ([Error]). + * * - Elm: [Result](http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Result) * - Haskell: [Data.Either](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html) * - Rust: [Result](https://doc.rust-lang.org/std/result/enum.Result.html) diff --git a/src/main/kotlin/com/mikebull94/result/ResultIterator.kt b/src/main/kotlin/com/mikebull94/result/ResultIterator.kt index a16da93..aa7209f 100644 --- a/src/main/kotlin/com/mikebull94/result/ResultIterator.kt +++ b/src/main/kotlin/com/mikebull94/result/ResultIterator.kt @@ -1,22 +1,39 @@ package com.mikebull94.result /** + * Creates an [Iterator] over the possibly contained [value][Ok.value]. + * The iterator yields one [value][Ok.value] if the [Result] is [Ok], otherwise throws [NoSuchElementException]. + * * - Rust: [Result.iter](https://doc.rust-lang.org/std/result/enum.Result.html#method.iter) + * + * @return [Iterator] over the possibly contained [value][Ok.value]. */ fun Result.iterator(): Iterator { return ResultIterator(this) } /** - * Rust: [Result.iter_mut](https://doc.rust-lang.org/std/result/enum.Result.html#method.iter_mut) + * Creates a [MutableIterator] over the possibly contained [value][Ok.value]. + * The iterator yields one [value][Ok.value] if the [Result] is [Ok], otherwise throws [NoSuchElementException]. + * + * - Rust: [Result.iter_mut](https://doc.rust-lang.org/std/result/enum.Result.html#method.iter_mut) + * + * @return The [MutableIterator] over the possibly contained [value][Ok.value]. */ fun Result.mutableIterator(): MutableIterator { return ResultIterator(this) } private class ResultIterator(private val result: Result) : MutableIterator { + + /** + * A flag indicating whether this [Iterator] has [yielded] its [Result]. + */ private var yielded = false + /** + * @return `true` if the [value][Ok.value] is not [yielded] and [Ok], `false` otherwise. + */ override fun hasNext(): Boolean { if (yielded) { return false @@ -28,6 +45,10 @@ private class ResultIterator(private val result: Result) : M } } + /** + * @return The [Result's][Result] [value][Ok.value] if not [yielded] and [Ok]. + * @throws NoSuchElementException if the [Result] is [yielded] or is not [Ok]. + */ override fun next(): V { if (!yielded && result is Ok) { yielded = true @@ -37,6 +58,9 @@ private class ResultIterator(private val result: Result) : M } } + /** + * Flags this [Iterator] as having [yielded] its [Result]. + */ override fun remove() { yielded = true } diff --git a/src/main/kotlin/com/mikebull94/result/Unwrap.kt b/src/main/kotlin/com/mikebull94/result/Unwrap.kt index 156bd91..19c056c 100644 --- a/src/main/kotlin/com/mikebull94/result/Unwrap.kt +++ b/src/main/kotlin/com/mikebull94/result/Unwrap.kt @@ -3,7 +3,11 @@ package com.mikebull94.result class UnwrapException(message: String) : Exception(message) /** + * Unwraps a [Result], yielding the [value][Ok.value]. + * * - Rust: [Result.unwrap](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap) + * + * @throws UnwrapException if the [Result] is an [Error], with a message containing the [error][Error.error]. */ fun Result.unwrap(): V { return when (this) { @@ -13,7 +17,12 @@ fun Result.unwrap(): V { } /** + * Unwraps a [Result], yielding the [value][Ok.value]. + * * - Rust: [Result.expect](https://doc.rust-lang.org/std/result/enum.Result.html#method.expect) + * + * @param message The message to include in the [UnwrapException] if the [Result] is an [Error]. + * @throws UnwrapException if the [Result] is an [Error], with the specified [message]. */ infix fun Result.expect(message: String): V { return when (this) { @@ -23,7 +32,11 @@ infix fun Result.expect(message: String): V { } /** + * Unwraps a [Result], yielding the [error][Error.error]. + * * - Rust: [Result.unwrap_err](https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_err) + * + * @throws UnwrapException if the [Result] is [Ok], with a message containing the [value][Ok.value]. */ fun Result.unwrapError(): E { return when (this) { @@ -33,7 +46,12 @@ fun Result.unwrapError(): E { } /** - * - Rust: [Reseult.expect_err](https://doc.rust-lang.org/std/result/enum.Result.html#method.expect_err) + * Unwraps a [Result], yielding the [error][Error.error]. + * + * - Rust: [Result.expect_err](https://doc.rust-lang.org/std/result/enum.Result.html#method.expect_err) + * + * @param message The message to include in the [UnwrapException] if the [Result] is [Ok]. + * @throws UnwrapException if the [Result] is [Ok], with the specified [message]. */ infix fun Result.expectError(message: String): E { return when (this) {