Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend string utils #810

Merged
merged 8 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ package io.spine.internal.dependency
)
object Protobuf {
private const val group = "com.google.protobuf"
const val version = "3.25.0"
const val version = "3.25.1"
/**
* The Java library containing proto definitions of Google Protobuf.
*/
Expand Down
2 changes: 1 addition & 1 deletion config
18 changes: 9 additions & 9 deletions dependencies.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


# Dependencies of `io.spine:spine-base:2.0.0-SNAPSHOT.193`
# Dependencies of `io.spine:spine-base:2.0.0-SNAPSHOT.194`

## Runtime
1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2.
Expand Down Expand Up @@ -38,15 +38,15 @@
* **Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/)
* **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)

1. **Group** : com.google.protobuf. **Name** : protobuf-java. **Version** : 3.25.0.
1. **Group** : com.google.protobuf. **Name** : protobuf-java. **Version** : 3.25.1.
* **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/)
* **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)

1. **Group** : com.google.protobuf. **Name** : protobuf-java-util. **Version** : 3.25.0.
1. **Group** : com.google.protobuf. **Name** : protobuf-java-util. **Version** : 3.25.1.
* **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/)
* **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)

1. **Group** : com.google.protobuf. **Name** : protobuf-kotlin. **Version** : 3.25.0.
1. **Group** : com.google.protobuf. **Name** : protobuf-kotlin. **Version** : 3.25.1.
* **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)

1. **Group** : org.checkerframework. **Name** : checker-compat-qual. **Version** : 2.5.3.
Expand Down Expand Up @@ -221,18 +221,18 @@
* **Project URL:** [https://github.com/google/j2objc/](https://github.com/google/j2objc/)
* **License:** [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)

1. **Group** : com.google.protobuf. **Name** : protobuf-java. **Version** : 3.25.0.
1. **Group** : com.google.protobuf. **Name** : protobuf-java. **Version** : 3.25.1.
* **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/)
* **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)

1. **Group** : com.google.protobuf. **Name** : protobuf-java-util. **Version** : 3.25.0.
1. **Group** : com.google.protobuf. **Name** : protobuf-java-util. **Version** : 3.25.1.
* **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/)
* **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)

1. **Group** : com.google.protobuf. **Name** : protobuf-kotlin. **Version** : 3.25.0.
1. **Group** : com.google.protobuf. **Name** : protobuf-kotlin. **Version** : 3.25.1.
* **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)

1. **Group** : com.google.protobuf. **Name** : protoc. **Version** : 3.25.0.
1. **Group** : com.google.protobuf. **Name** : protoc. **Version** : 3.25.1.
* **Project URL:** [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/)
* **License:** [BSD-3-Clause](https://opensource.org/licenses/BSD-3-Clause)
* **License:** [The Apache Software License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
Expand Down Expand Up @@ -784,4 +784,4 @@

The dependencies distributed under several licenses, are used according their commercial-use-friendly license.

This report was generated on **Fri Nov 24 17:06:57 WET 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
This report was generated on **Tue Dec 12 23:35:01 WET 2023** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject.
-->
<groupId>io.spine</groupId>
<artifactId>base</artifactId>
<version>2.0.0-SNAPSHOT.193</version>
<version>2.0.0-SNAPSHOT.194</version>

<inceptionYear>2015</inceptionYear>

Expand All @@ -32,19 +32,19 @@ all modules and does not describe the project structure per-subproject.
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.25.0</version>
<version>3.25.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.25.0</version>
<version>3.25.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-kotlin</artifactId>
<version>3.25.0</version>
<version>3.25.1</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -174,7 +174,7 @@ all modules and does not describe the project structure per-subproject.
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
<version>3.25.0</version>
<version>3.25.1</version>
</dependency>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
Expand Down
43 changes: 21 additions & 22 deletions src/main/java/io/spine/annotation/Internal.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,36 +33,35 @@
import java.lang.annotation.Target;

/**
* Annotates a program element (class, method, package, etc.) which is not a part of a public API,
* and thus should not be used by people who are not members of the team developing the module
* containing this program element.
* Marks a program element (class, method, package, etc.) as internal to the Spine Event Engine,
* indicating it is NOT part of the public API and hence not intended for use outside
* the module's development team.
*
* <p>If the annotation is used for a constructor, a <strong>field</strong>,
* a <strong>method</strong>, or a <strong>package</strong>, it means
* that corresponding element is internal to the Spine Event Engine and as such should
* not be used programmers using the framework.
* <p>The usage scenarios for the annotation vary depending on the element it is applied to.
*
* <p>If the annotation is used for a <strong>type</strong> it means one of the following.
* <h3>If applied to a constructor, field, method, or package</h3>
*
* <p><strong>First reason.</strong> This type is internal to the Spine Event Engine framework,
* and is not meant to be used directly by the framework users.</p>
* <p>The annotated program element is not intended for usage by the framework users
*
* <p><strong>Second reason.</strong> The type is internal to a bounded context, artifact of which
* exposes the type to the outside world (presumably for historical reasons).</p>
* <h3>If applied to a type</h3>
*
* <p>When so, the type with this annotation can be used only inside the bounded context
* which declares it.
* <p>The annotation applied to a type could mean either:
* <ul>
* <li><strong>Option 1:</strong> The type is internal to the Spine Engine framework,
* hence should not be directly used by the framework users.
*
* <p>The type must not be used neither for inbound (i.e. being sent to the bounded context
* which declares this type) nor for outbound communication (i.e. being sent by this bounded
* context outside). An attempt to use the type otherwise will cause runtime error.</p>
* <li><strong>Option 2:</strong> The type is specific to a bounded context in which it may be
* exposed externally because of technical or historical reasons.
* Attempting to use the type for inbound or outbound communication will
* trigger runtime errors.
* </ul>
*
* @apiNote If you plan to implement an extension which is going to be wired into
* the framework, you may want to use the internal parts. Please consider consulting with the Spine
* development team, as the internal APIs do not have the same stability guarantee as public ones.
*
* <p>See {@link SPI} annotation if you plan to write an extension of the framework.
* <p>See also {@link SPI} for annotations related to framework extensions.
*
* @apiNote Implementing an extension to wire into the framework might tempt you
* to use these internal parts.
* However, be aware that they might have less stability than public APIs.
* Consultation with the Spine development team is strongly recommended in these cases.
* @see SPI
*/
@Internal
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/io/spine/string/Separator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public enum class Separator(
public val value: String,

/**
* The representation of [value] to be used for debugging multi-line strings terminated.
* by [system line separator][nl].
* The representation of [value] to be used for debugging multi-line strings
* terminated by [system line separator][nl].
*/
public val escaped: String
) {
Expand Down
60 changes: 51 additions & 9 deletions src/main/kotlin/io/spine/string/Strings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/

@file:JvmName("Strings")
@file:Suppress("TooManyFunctions") // Extension functions for `String` are grouped here.

package io.spine.string

Expand Down Expand Up @@ -57,8 +58,8 @@ public fun <T> Iterable<T>.joinBackticked(): String =
/**
* Obtains the same string but with the first capital letter.
*
* If the first char of the string cannot be capitalized (e.g., is not a letter, is already
* capitalized, etc.), obtains the same string.
* If the first char of the string cannot be capitalized (e.g., is not a letter,
* is already capitalized, etc.), obtains the same string.
*/
public fun String.titleCase(): String =
replaceFirstChar { it.titlecase() }
Expand All @@ -77,6 +78,11 @@ public fun String.titleCase(): String =
public fun String.camelCase(): String =
split("_").camelCase()

/**
* System-dependent line separator.
*/
private val NL: String = Separator.nl()

/**
* Trims the common indent from all the lines, as well as the trailing whitespace.
*
Expand All @@ -90,28 +96,64 @@ public fun String.trimWhitespace(): String {
val trimmedLines = lines.map {
it.trimEnd()
}
return trimmedLines.joinToString(Separator.nl())
return trimmedLines.joinToString(NL)
}

/**
* Replaces [Separator.LF] used by Kotlin string utilities for splitting by lines,
* with [Separator.nl] so that we don't have issues when writing generated texts under Windows.
* Replaces [Separator.LF] with [Separator.system].
*
* [Separator.LF] is used by Kotlin string utilities for splitting by lines.
* This may cause issues when writing generated texts under Windows.
*
* If you could not find a replacement for system-dependent line separation in
* `io.spine.string` package, please use this function after a Kotlin string utility call.
*
* @see String.pi
* @see String.tm
* @see String.ti
*/
private fun String.fixLineEndings(): String = replace(Separator.LF.value, Separator.nl())
public fun String.naturalizeEndings(): String = replace(Separator.LF.value, NL)

/**
* Trims indentation similarly to [String.trimIndent] but preserving system line separators.
*/
public fun String.ti(): String = trimIndent().fixLineEndings()
public fun String.ti(): String = trimIndent().naturalizeEndings()

/**
* The same as [trimMargin] but with system-dependent line separator.
*/
public fun String.tm(): String = trimMargin().naturalizeEndings()

/**
* Prepends indentation similarly to [String.prependIndent] but preserving system line separators.
*
* @see Iterable.indent
*/
public fun String.pi(indent: String = Indent.defaultJavaIndent.value): String =
prependIndent(indent).fixLineEndings()
prependIndent(indent).naturalizeEndings()

/**
* Joins the elements of this `Iterable` into a single string having each item on a separate line.
*
* The lines are delimited with system line separator.
*/
public fun Iterable<*>.joinByLines(): String =
joinToString(separator = Separator.nl())
joinToString(separator = NL)

/**
* Joins these lines of code into a code block, accounting for extra indent.
*
* Similar to [prependIndent] but with system-dependent line separator.
*
* @param step
* the indentation of each level.
* @param level
* the number of indentation levels to add. If zero, no indentation would be added.
* @see String.pi
*/
public fun Iterable<String>.indent(step: Indent, level: Int): String {
val indentation = step.atLevel(level)
return joinToString(NL) {
indentation + it
}
}
21 changes: 21 additions & 0 deletions src/test/kotlin/io/spine/string/StringsSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,25 @@ class StringsSpec {
val value = "some value"
value.stringify() shouldBe value
}

@Test
fun `indent lines`() {
val source = """
line 1
line 2
line 3
""".ti().lines()

source.indent(Indent(size = 2), level = 2) shouldBe """
| line 1
| line 2
| line 3
""".tm()

source.indent(Indent(size = 3), level = 0) shouldBe """
|line 1
|line 2
|line 3
""".tm()
}
}
2 changes: 1 addition & 1 deletion version.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

val versionToPublish: String by extra("2.0.0-SNAPSHOT.193")
val versionToPublish: String by extra("2.0.0-SNAPSHOT.194")
Loading