/kpipe

A kotlin-native library introducing a functional-style pipe.

Primary LanguageKotlinApache License 2.0Apache-2.0

kpipe

tests branches

Pipe functions that allow for a more functional style of programming. They support chains of transformation up to 11 in size, providing excellent DX on top.

The library includes:

  • pipe - a function that pipes the result of one function to the next as a parameter
  • kpipe- a function that pipes the result of one function to the next as context receiver and the initial value as a parameter

The functions are implemented as a invoke override on the companion, so you can name them whatever you want with typealiases.

a little preview

class PipeExample {
fun interface ValueFactory<PRIMITIVE : Any, TARGET : Any> {
fun of(value: PRIMITIVE): TARGET
}
@JvmInline
value class EID private constructor(private val value: String) {
companion object : ValueFactory<String, EID> {
override fun of(value: String) = pipe(
value,
{ it.isNotEmpty() && it.isNotBlank() },
::require,
{ EID(value) }
)
}
}
sealed interface Event {
val id: EID
data class Initialized(override val id: EID, val timestamp: String) : Event
}
interface EventStore {
fun get(id: EID): Event?
fun store(event: Event): Result<Unit>
}
fun InMemoryEventStore() = object : EventStore {
private val storage = mutableMapOf<EID, Event>()
override fun get(id: EID) = pipe(
id,
storage::get
)
override fun store(event: Event) = pipe(
event,
{ storage[it.id] = it },
Result.Companion::success
)
}
@Test
fun `you can't create a blank EID`() {
pipe(
runCatching { EID.of("") }.exceptionOrNull(),
{ assertIs<IllegalArgumentException>(it) } // kotlin does not allow method reference with generics
)
}
@Test
fun `can store and retrieve events`() {
// given
val uut = InMemoryEventStore()
val id = EID.of("1")
val event = Event.Initialized(id, "2077-03-03T10:15:30Z")
// when/then
pipe(
id,
uut::get,
::assertNull,
)
kpipe(
event,
{ uut.store(this) },
{ isSuccess },
{ assertTrue("Failed for event $it") { this } },
)
pipe(
id,
uut::get,
{ expect(event) { it } }
)
}
}

currently available via JitPack

repositories {
    // all the other ones that you might need...

    maven { url = uri("https://jitpack.io") }
}

// and then

dependencies {
    // all the other ones that you might need...
    
    testImplementation("com.github.bkosm:kpipe:1.0.0")
}

you decide on the features!

Drop an issue with what functionality you could use in your Kotlin tuple or submit a PR!