All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.hoc081098.flowext.Event.kt Maven / Gradle / Ivy

/*
 * MIT License
 *
 * Copyright (c) 2021-2024 Petrus Nguyễn Thái Học
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

@file:Suppress("NOTHING_TO_INLINE")

package com.hoc081098.flowext

import dev.drewhamilton.poko.Poko

/**
 * Represents the reactive signal types: `value`, `error` and `complete`,
 * and holds their parameter values (a value, a [Throwable], nothing).
 *
 * Sequence grammar:
 * `value* (error | complete)`
 */
public sealed interface Event {
  /**
   * A value event containing the given [value].
   */
  @Poko
  public class Value(public val value: T) : Event {
    override fun toString(): String = "Event.Value($value)"
  }

  /**
   * A error event containing the [error].
   */
  @Poko
  public class Error(public val error: Throwable) : Event {
    override fun toString(): String = "Event.Error($error)"
  }

  /**
   * Complete event.
   */
  public data object Complete : Event {
    override fun toString(): String = "Event.Complete"
  }
}

/**
 * When this [Event] is a [Event.Value], return a [Event.Value] containing transformed value using [transform].
 * Otherwise, returns itself.
 */
public inline fun  Event.map(transform: (T) -> R): Event = when (this) {
  Event.Complete -> Event.Complete
  is Event.Error -> this
  is Event.Value -> Event.Value(transform(value))
}

/**
 * Returns the result of applying [transform] to this [Event]'s [value][Event.Value.value] if this is a [Event.Value].
 * Otherwise, returns itself.
 *
 * Slightly different from [map] in that [transform] is expected to
 * return an [Event] (which could be [Event.Error] or [Event.Complete]).
 */
public inline fun  Event.flatMap(transform: (T) -> Event): Event = when (this) {
  Event.Complete -> Event.Complete
  is Event.Error -> this
  is Event.Value -> transform(value)
}

/**
 * Returns the encapsulated [value][Event.Value.value] if this [Event] is a [Event.Value], otherwise returns `null`.
 */
public inline fun  Event.valueOrNull(): T? = valueOrElse { null }

/**
 * Returns the encapsulated [value][Event.Value.value] if this [Event] is a [Event.Value], otherwise returns [defaultValue].
 */
public inline fun  Event.valueOrDefault(defaultValue: T): T? = valueOrElse { defaultValue }

/**
 * Returns the encapsulated value if this [Event] is a [Event.Value].
 * If this is [Event.Error], throws the encapsulated [error][Event.Error.error].
 * Otherwise, throws a [NoSuchElementException].
 */
public inline fun  Event.valueOrThrow(): T =
  valueOrElse { throw it ?: NoSuchElementException("$this has no value!") }

/**
 * Returns the encapsulated [value][Event.Value.value] if this [Event] is a [Event.Value],
 * otherwise returns the result of calling [defaultValue] function.
 *
 * The function [defaultValue] will be called with `null` if this [Event] is [Event.Complete].
 */
public inline fun  Event.valueOrElse(defaultValue: (Throwable?) -> T): T = when (this) {
  Event.Complete -> defaultValue(null)
  is Event.Error -> defaultValue(error)
  is Event.Value -> value
}

/**
 * Returns the encapsulated [error][Event.Error.error] if this [Event] is an [Event.Error], otherwise returns `null`.
 */
public inline fun  Event.errorOrNull(): Throwable? = when (this) {
  Event.Complete -> null
  is Event.Error -> error
  is Event.Value -> null
}

/**
 * Returns the encapsulated [error][Event.Error.error] if this [Event] is an [Event.Error].
 * Otherwise, throws a [NoSuchElementException].
 */
public inline fun  Event.errorOrThrow(): Throwable =
  errorOrNull() ?: throw NoSuchElementException("$this has no error!")




© 2015 - 2025 Weber Informatics LLC | Privacy Policy