diff --git a/src/main/kotlin/io/spine/string/Stringifiers.kt b/src/main/kotlin/io/spine/string/Stringify.kt similarity index 81% rename from src/main/kotlin/io/spine/string/Stringifiers.kt rename to src/main/kotlin/io/spine/string/Stringify.kt index be29a2aefe..8f5d7ed71a 100644 --- a/src/main/kotlin/io/spine/string/Stringifiers.kt +++ b/src/main/kotlin/io/spine/string/Stringify.kt @@ -23,6 +23,9 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +@file:JvmName("Stringify") + package io.spine.string import com.google.common.escape.Escaper @@ -34,9 +37,59 @@ import java.lang.reflect.Type import kotlin.reflect.KClass /** - * Utility class for working with `Stringifier`s. + * Obtains a string representation of this object using a [Stringifier] for the object type. + * + * @see Stringifiers.toString + */ +public inline fun T.stringify(): String = + Stringifiers.toString(this, T::class.java) + +/** + * Same as [Stringifiers.fromString] for brevity in Kotlin code. + */ +public inline fun fromString(str: String): T = + Stringifiers.fromString(str, T::class.java) + +/** + * Same as [Stringifier.fromString] accepting [KClass] instead of [Class]. + */ +public fun fromString(str: String, cls: KClass): T = + Stringifiers.fromString(str, cls.java) + +/** + * Same as [Stringifiers.newForListOf] for brevity in Kotlin code. */ -@Suppress("TooManyFunctions") // need to gather all of them here for easier usage. +public inline fun listStringifier(): Stringifier> = + Stringifiers.newForListOf(T::class.java) + +/** + * Same as [Stringifiers.newForListOf] for brevity in Kotlin code. + */ +public inline fun listStringifier(delimiter: Char): Stringifier> = + Stringifiers.newForListOf(T::class.java, delimiter) + +/** + * Same as [Stringifiers.newForMapOf] for brevity in Kotlin code. + */ +public inline fun mapStringifier(): Stringifier> = + Stringifiers.newForMapOf(K::class.java, V::class.java) + +/** + * Same as [Stringifiers.newForMapOf] for brevity in Kotlin code. + */ +public inline fun mapStringifier( + delimiter: Char +): Stringifier> = Stringifiers.newForMapOf(K::class.java, V::class.java, delimiter) + +/** + * Utility object for working with `Stringifier`s. + * + * **API Note**: This object is Kotlin port of the `Stringifiers` class from Java. + * It is kept as an object, rather than a group of top-level functions, to preserve backward + * compatibility with the existing Java code. It is expected that it will be gradually + * migrated to top-level functions with an appropriate deprecation cycle. + */ +@Suppress("TooManyFunctions") // Need to gather all of them here for easier usage. public object Stringifiers { /** @@ -59,6 +112,7 @@ public object Stringifiers { * * The same as [toString] but with the ability for static import in Java. */ + @JvmStatic public fun stringify(obj: T): String = toString(obj) /** @@ -102,18 +156,6 @@ public object Stringifiers { return result!! } - /** - * Same as [fromString] accepting [KClass] instead of [Class]. - */ - public fun fromString(str: String, cls: KClass): T = - fromString(str, cls.java) - - /** - * Same as [fromString] for brevity in Kotlin code. - */ - public inline fun fromString(str: String): T = - fromString(str, T::class.java) - /** * Obtains `Stringifier` for the map with default delimiter for the passed map elements. * @@ -134,12 +176,6 @@ public object Stringifiers { ): Stringifier> = MapStringifier(keyClass, valueClass) - /** - * Same as [newForMapOf] for brevity in Kotlin code. - */ - public inline fun newForMapOf(): Stringifier> = - newForMapOf(K::class.java, V::class.java) - /** * Obtains `Stringifier` for the map with custom delimiter for the passed map elements. * @@ -161,13 +197,6 @@ public object Stringifiers { delimiter: Char ): Stringifier> = MapStringifier(keyClass, valueClass, delimiter) - /** - * Same as [newForMapOf] for brevity in Kotlin code. - */ - public inline fun newForMapOf( - delimiter: Char - ): Stringifier> = newForMapOf(K::class.java, V::class.java, delimiter) - /** * Obtains `Stringifier` for `Boolean` values. */ @@ -225,12 +254,6 @@ public object Stringifiers { public fun newForListOf(elementClass: Class): Stringifier> = ListStringifier(elementClass) - /** - * Same as [newForListOf] for brevity in Kotlin code. - */ - public inline fun newForListOf(): Stringifier> = - newForListOf(T::class.java) - /** * Obtains `Stringifier` for a list with the custom delimiter for the passed list elements. * @@ -247,12 +270,6 @@ public object Stringifiers { delimiter: Char ): Stringifier> = ListStringifier(elementClass, delimiter) - /** - * Same as [newForListOf] for brevity in Kotlin code. - */ - public inline fun newForListOf(delimiter: Char): Stringifier> = - newForListOf(T::class.java, delimiter) - /** * Obtains a `Stringifier` for the passed `enum` class. * diff --git a/src/main/kotlin/io/spine/string/Strings.kt b/src/main/kotlin/io/spine/string/Strings.kt index 334585c7d4..08c2dac068 100644 --- a/src/main/kotlin/io/spine/string/Strings.kt +++ b/src/main/kotlin/io/spine/string/Strings.kt @@ -28,6 +28,14 @@ package io.spine.string +/** + * This file contains extension functions for obtaining standard string + * representation of various objects. For string representations using [Stringifier], + * please see [io.spine.string.Stringifiers]. + */ +@Suppress("unused") +private const val ABOUT = "" + /** * Joins these strings into a `CamelCase` string. * @@ -102,14 +110,6 @@ public fun String.ti(): String = trimIndent().fixLineEndings() public fun String.pi(indent: String = Indent.defaultJavaIndent.value): String = prependIndent(indent).fixLineEndings() -/** - * Obtains a string representation of this object using a [Stringifier] for the object type. - * - * @see Stringifiers.toString - */ -public inline fun T.stringify(): String = - Stringifiers.toString(this, T::class.java) - /** * Joins the elements of this `Iterable` into a single string having each item on a separate line. */ diff --git a/src/test/java/io/spine/string/StringifyJavaSpec.java b/src/test/java/io/spine/string/StringifyJavaSpec.java new file mode 100644 index 0000000000..ccd4a92531 --- /dev/null +++ b/src/test/java/io/spine/string/StringifyJavaSpec.java @@ -0,0 +1,44 @@ +/* + * Copyright 2023, TeamDev. All rights reserved. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.spine.string; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static com.google.common.truth.Truth.assertThat; +import static io.spine.string.Stringifiers.stringify; + +@DisplayName("`Stringify` should") +class StringifyJavaSpec { + + @Test + @DisplayName("provide `stringify()` method") + void provideStringifyMethod() { + var value = "foo-bar"; + assertThat(stringify(value)).isEqualTo(value); + } +} diff --git a/src/test/kotlin/io/spine/string/StringifiersSpec.kt b/src/test/kotlin/io/spine/string/StringifiersSpec.kt index 95e721c646..81b43cd8be 100644 --- a/src/test/kotlin/io/spine/string/StringifiersSpec.kt +++ b/src/test/kotlin/io/spine/string/StringifiersSpec.kt @@ -36,7 +36,6 @@ import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldContain import io.spine.base.Identifier import io.spine.base.Time -import io.spine.string.Stringifiers.fromString import io.spine.string.Stringifiers.stringify import io.spine.test.string.STask import io.spine.test.string.STaskId @@ -60,7 +59,7 @@ internal class StringifiersSpec : UtilityClassTest(Stringifiers::c @Nested @DisplayName("stringify") - internal inner class Stringify { + internal inner class StringifyKt { @Test fun boolean() = checkStringifies(false, "false") @@ -122,7 +121,7 @@ internal class StringifiersSpec : UtilityClassTest(Stringifiers::c @Test fun List() { val stamps: List = createList() - val stringifier = Stringifiers.newForListOf(DELIMITER) + val stringifier = listStringifier(DELIMITER) val out = stringifier.toString(stamps) out shouldContain DELIMITER.toString() @@ -136,7 +135,7 @@ internal class StringifiersSpec : UtilityClassTest(Stringifiers::c @Test fun Map() { val stamps = createMap() - val stringifier = Stringifiers.newForMapOf(DELIMITER) + val stringifier = mapStringifier(DELIMITER) val out = stringifier.toString(stamps) out shouldContain DELIMITER.toString() @@ -187,7 +186,7 @@ internal class StringifiersSpec : UtilityClassTest(Stringifiers::c @Test fun List() { val numbers: List = ImmutableList.of(100, 200, -300) - val stringifier = Stringifiers.newForListOf() + val stringifier = listStringifier() val numString = stringifier.toString(numbers) val parsed = stringifier.fromString(numString)