diff --git a/.gitignore b/.gitignore index 44746f11..aa1d29df 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ captures/ # IntelliJ *.iml .idea/ +.kotlin/ # Android Studio 3 in .gitignore file. .idea/caches diff --git a/README.md b/README.md index 89275150..b069bde4 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,6 @@ ![badge-support-js-ir] ![badge-support-linux-arm] - - Configurable, streamable, efficient and extensible Encoding/Decoding for Kotlin Multiplatform. **Base16 (a.k.a. "hex")** @@ -39,8 +35,6 @@ Configurable, streamable, efficient and extensible Encoding/Decoding for Kotlin - Default [RFC 4648 section 4](https://www.ietf.org/rfc/rfc4648.html#section-4) - UrlSafe [RFC 4648 section 5](https://www.ietf.org/rfc/rfc4648.html#section-5) -A full list of `kotlin-components` projects can be found [HERE](https://kotlin-components.matthewnelson.io) - ### Usage **Configure `EncoderDecoder`(s) to your needs** @@ -56,7 +50,7 @@ val base16 = Base16 { // Use lowercase instead of uppercase characters when encoding encodeToLowercase = true - // Use constant-time operations for sensitive data + // Use constant-time operations when encoding/decoding sensitive data isConstantTime = true } diff --git a/RELEASING.md b/RELEASING.md index 64d43cdb..c5d4369e 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -2,4 +2,9 @@ See [KotlinCrypto/documentation/RELEASING.md][url-kotlincrypto-releasing] +Additionally, publish dokka documentation updates +```bash +./gh-pages/publish.sh +``` + [url-kotlincrypto-releasing]: https://github.com/KotlinCrypto/documentation/blob/master/RELEASING.md diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index 65d83f0f..ec02fd76 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -18,6 +18,7 @@ plugins { } dependencies { + implementation(libs.gradle.dokka) implementation(libs.gradle.kmp.configuration) implementation(libs.gradle.kotlin) implementation(libs.gradle.publish.maven) diff --git a/build-logic/src/main/kotlin/-KmpConfigurationExtension.kt b/build-logic/src/main/kotlin/-KmpConfigurationExtension.kt index 93327253..887fcaa1 100644 --- a/build-logic/src/main/kotlin/-KmpConfigurationExtension.kt +++ b/build-logic/src/main/kotlin/-KmpConfigurationExtension.kt @@ -77,7 +77,7 @@ fun KmpConfigurationExtension.configureShared( mingwAll() common { - if (publish) pluginIds("publication") + if (publish) pluginIds("publication", "dokka") sourceSetTest { dependencies { diff --git a/build-logic/src/main/kotlin/dokka.gradle.kts b/build-logic/src/main/kotlin/dokka.gradle.kts new file mode 100644 index 00000000..91bfc201 --- /dev/null +++ b/build-logic/src/main/kotlin/dokka.gradle.kts @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Matthew Nelson + * + * Licensed 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 + * + * https://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. + **/ +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTaskPartial +import java.net.URI + +plugins { + id("org.jetbrains.dokka") +} + +tasks.withType().configureEach { + suppressInheritedMembers = true + + dokkaSourceSets.configureEach { + includes.from("README.md") + noStdlibLink = true + + sourceLink { + localDirectory = rootDir + remoteUrl = URI("https://github.com/05nelsonm/encoding/tree/master").toURL() + remoteLineSuffix = "#L" + } + + documentedVisibilities.set(setOf( + Visibility.PUBLIC, + Visibility.PROTECTED, + )) + } +} diff --git a/build.gradle.kts b/build.gradle.kts index 344fdff7..65479090 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { + alias(libs.plugins.dokka) alias(libs.plugins.binary.compat) alias(libs.plugins.multiplatform) apply(false) } diff --git a/gh-pages/publish.sh b/gh-pages/publish.sh new file mode 100755 index 00000000..38a3d199 --- /dev/null +++ b/gh-pages/publish.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Copyright (c) 2023 Matthew Nelson +# +# Licensed 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 +# +# https://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. +set -e + +readonly DIR_SCRIPT="$( cd "$( dirname "$0" )" >/dev/null && pwd )" + +trap 'rm -rf "$DIR_SCRIPT/encoding"' EXIT + +cd "$DIR_SCRIPT" +git clone -b gh-pages --single-branch https://github.com/05nelsonm/encoding.git +rm -rf "$DIR_SCRIPT/encoding/"* +echo "encoding.matthewnelson.io" > "$DIR_SCRIPT/encoding/CNAME" + +cd .. +./gradlew clean -DKMP_TARGETS_ALL +./gradlew dokkaHtmlMultiModule -DKMP_TARGETS_ALL +cp -aR build/dokka/htmlMultiModule/* gh-pages/encoding + +cd "$DIR_SCRIPT/encoding" +git add --all +git commit -S --message "Update dokka docs" +git push diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f0b8d8ec..ffeff037 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,6 @@ [versions] gradle-binary-compat = "0.16.3" +gradle-dokka = "1.9.20" gradle-kmp-configuration = "0.3.2" gradle-kotlin = "1.9.24" gradle-publish-maven = "0.29.0" @@ -7,6 +8,7 @@ gradle-publish-maven = "0.29.0" immutable = "0.1.4" [libraries] +gradle-dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "gradle-dokka" } gradle-kmp-configuration = { module = "io.matthewnelson:gradle-kmp-configuration-plugin", version.ref = "gradle-kmp-configuration" } gradle-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "gradle-kotlin" } gradle-publish-maven = { module = "com.vanniktech:gradle-maven-publish-plugin", version.ref = "gradle-publish-maven" } @@ -15,4 +17,5 @@ immutable-collections = { module = "io.matthewnelson.immutable:collections", ver [plugins] binary-compat = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "gradle-binary-compat" } +dokka = { id = "org.jetbrains.dokka", version.ref = "gradle-dokka" } multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "gradle-kotlin" } diff --git a/library/base16/README.md b/library/base16/README.md new file mode 100644 index 00000000..2c52200a --- /dev/null +++ b/library/base16/README.md @@ -0,0 +1,5 @@ +# Module base16 + +Base16 (a.k.a. "hex") encoding/decoding in accordance with [RFC 4648 section 8][url-rfc] + +[url-rfc]: https://www.ietf.org/rfc/rfc4648.html#section-8 diff --git a/library/base32/README.md b/library/base32/README.md new file mode 100644 index 00000000..f6ee501b --- /dev/null +++ b/library/base32/README.md @@ -0,0 +1,7 @@ +# Module base32 + +Base32 encoding/decoding in accordance with [Crockford][url-crockford], [RFC 4648 section 6][url-rfc-6], [RFC 4648 section 6][url-rfc-7] + +[url-crockford]: https://www.crockford.com/base32.html +[url-rfc-6]: https://www.ietf.org/rfc/rfc4648.html#section-6 +[url-rfc-7]: https://www.ietf.org/rfc/rfc4648.html#section-7 diff --git a/library/base32/src/commonMain/kotlin/io/matthewnelson/component/encoding/base32/Base32.kt b/library/base32/src/commonMain/kotlin/io/matthewnelson/component/encoding/base32/Base32.kt index 9fbf7142..b18cf842 100644 --- a/library/base32/src/commonMain/kotlin/io/matthewnelson/component/encoding/base32/Base32.kt +++ b/library/base32/src/commonMain/kotlin/io/matthewnelson/component/encoding/base32/Base32.kt @@ -35,6 +35,7 @@ import io.matthewnelson.encoding.core.Encoder.Companion.encodeToCharArray import io.matthewnelson.encoding.core.Encoder.Companion.encodeToString import kotlin.jvm.JvmOverloads +/** @suppress */ @Deprecated( message = "Replaced by EncoderDecoder. Will be removed in future versions.", replaceWith = ReplaceWith( diff --git a/library/base64/README.md b/library/base64/README.md new file mode 100644 index 00000000..eab36376 --- /dev/null +++ b/library/base64/README.md @@ -0,0 +1,6 @@ +# Module base64 + +Base64 encoding/decoding in accordance with [RFC 4648 section 4][url-rfc-4], [RFC 4648 section 5][url-rfc-5] + +[url-rfc-4]: https://www.ietf.org/rfc/rfc4648.html#section-4 +[url-rfc-5]: https://www.ietf.org/rfc/rfc4648.html#section-5 diff --git a/library/base64/src/commonMain/kotlin/io/matthewnelson/component/base64/Base64.kt b/library/base64/src/commonMain/kotlin/io/matthewnelson/component/base64/Base64.kt index a2c1407e..37602d9d 100644 --- a/library/base64/src/commonMain/kotlin/io/matthewnelson/component/base64/Base64.kt +++ b/library/base64/src/commonMain/kotlin/io/matthewnelson/component/base64/Base64.kt @@ -40,6 +40,7 @@ import io.matthewnelson.encoding.core.Encoder.Companion.encodeToCharArray import io.matthewnelson.encoding.core.Encoder.Companion.encodeToString import kotlin.jvm.JvmOverloads +/** @suppress */ @Deprecated( message = "Replaced by EncoderDecoder. Will be removed in future versions.", replaceWith = ReplaceWith( diff --git a/library/core/README.md b/library/core/README.md new file mode 100644 index 00000000..79bae147 --- /dev/null +++ b/library/core/README.md @@ -0,0 +1,4 @@ +# Module core + +Core primitives for encoding/decoding operations, serving as the foundation to other +higher level implementations. diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Decoder.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Decoder.kt index 769aa464..1cb6b0c3 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Decoder.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Decoder.kt @@ -149,6 +149,7 @@ public sealed class Decoder(public val config: C) { public final override fun close() { isClosed = true } public final override fun isClosed(): Boolean = isClosed + /** @suppress */ public final override fun toString(): String = "${this@Decoder}.Decoder.Feed@${hashCode()}" @Throws(EncodingException::class) @@ -221,6 +222,7 @@ public sealed class Decoder(public val config: C) { * * @see [decodeToByteArrayOrNull] * @throws [EncodingException] if decoding failed. + * @suppress * */ @JvmStatic @Throws(EncodingException::class) @@ -231,6 +233,7 @@ public sealed class Decoder(public val config: C) { } } + /** @suppress */ @JvmStatic @Deprecated(message = "Should not utilize. Underlying Byte to Char conversion can produce incorrect results") public fun ByteArray.decodeToByteArrayOrNull(decoder: Decoder<*>): ByteArray? { diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Encoder.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Encoder.kt index 1d5a6df9..c37eecdc 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Encoder.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/Encoder.kt @@ -124,6 +124,7 @@ public sealed class Encoder(config: C): Decoder(con public final override fun close() { isClosed = true } public final override fun isClosed(): Boolean = isClosed + /** @suppress */ public final override fun toString(): String = "${this@Encoder}.Encoder.Feed@${hashCode()}" protected abstract fun consumeProtected(input: Byte) @@ -199,6 +200,7 @@ public sealed class Encoder(config: C): Decoder(con * data, but is something that can occur with Base16 (hex) * as it produces 2 characters of output for every 1 byte * of input. + * @suppress * */ @JvmStatic @Throws(EncodingSizeException::class) diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/EncoderDecoder.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/EncoderDecoder.kt index 4807456d..4fb41def 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/EncoderDecoder.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/EncoderDecoder.kt @@ -302,28 +302,34 @@ public abstract class EncoderDecoder(config: C): Encod @JvmField public val name: String = name.trim() + /** @suppress */ override fun equals(other: Any?): Boolean { return other is Setting && other.name == name } + /** @suppress */ override fun hashCode(): Int { return 17 * 31 + name.hashCode() } + /** @suppress */ override fun toString(): String = "$name: $value" } + /** @suppress */ final override fun equals(other: Any?): Boolean { return other is Config && other::class == this::class && other.toString() == toString() } + /** @suppress */ final override fun hashCode(): Int { return 17 * 31 + toString().hashCode() } + /** @suppress */ final override fun toString(): String { return StringBuilder().apply { append("EncoderDecoder.Config [") @@ -488,6 +494,7 @@ public abstract class EncoderDecoder(config: C): Encod * */ protected abstract fun name(): String + /** @suppress */ final override fun equals(other: Any?): Boolean { return other is EncoderDecoder<*> && other::class == this::class @@ -495,6 +502,7 @@ public abstract class EncoderDecoder(config: C): Encod && other.config.hashCode() == config.hashCode() } + /** @suppress */ final override fun hashCode(): Int { var result = 17 result = result * 31 + name().hashCode() @@ -502,6 +510,7 @@ public abstract class EncoderDecoder(config: C): Encod return result } + /** @suppress */ final override fun toString(): String { return "EncoderDecoder[${name()}]@${hashCode()}" } diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/internal/InternalEncodingApi.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/internal/InternalEncodingApi.kt index 4805fd94..22fc30d2 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/internal/InternalEncodingApi.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/internal/InternalEncodingApi.kt @@ -26,6 +26,8 @@ package io.matthewnelson.encoding.core.internal * the following compiler argument: * * -Xopt-in=io.matthewnelson.encoding.core.internal.InternalEncodingApi + * + * @suppress * */ @RequiresOptIn @MustBeDocumented diff --git a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/util/DecoderAction.kt b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/util/DecoderAction.kt index e5415346..3b9f13a3 100644 --- a/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/util/DecoderAction.kt +++ b/library/core/src/commonMain/kotlin/io/matthewnelson/encoding/core/util/DecoderAction.kt @@ -27,7 +27,7 @@ import kotlin.jvm.JvmField public fun interface DecoderAction { /** - * Convert decoder input character to its bitwise integer + * Convert decoder input character to its bitwise integer value. * */ public fun convert(input: Char): Int @@ -49,7 +49,7 @@ public fun interface DecoderAction { * * val bits = "48656C6C6F20576F726C6421".map { char -> * parser.parse(char, isConstantTime = true) - * ?: error("Invalid Char[$char]) + * ?: error("Invalid Char[$char]") * } * * @param [action] Pairs of character ranges and their associated [DecoderAction]