Skip to content
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
2 changes: 1 addition & 1 deletion workflow-core/api/workflow-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ public final class com/squareup/workflow/WorkflowActionKt {
public static final fun action (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lcom/squareup/workflow/WorkflowAction;
public static final fun action (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;)Lcom/squareup/workflow/WorkflowAction;
public static synthetic fun action$default (Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/squareup/workflow/WorkflowAction;
public static final fun applyTo (Lcom/squareup/workflow/WorkflowAction;Ljava/lang/Object;)Lkotlin/Pair;
public static final fun applyTo (Lcom/squareup/workflow/WorkflowAction;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Lkotlin/Pair;
}

public final class com/squareup/workflow/WorkflowIdentifier {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import com.squareup.workflow.WorkflowAction.Updater
*
* See [renderChild].
*/
interface RenderContext<StateT, in OutputT : Any> {
interface RenderContext<StateT, in OutputT> {

/**
* Accepts a single [WorkflowAction], invokes that action by calling [WorkflowAction.apply]
Expand Down Expand Up @@ -94,7 +94,7 @@ interface RenderContext<StateT, in OutputT : Any> {
* @param key An optional string key that is used to distinguish between workflows of the same
* type.
*/
fun <ChildPropsT, ChildOutputT : Any, ChildRenderingT> renderChild(
fun <ChildPropsT, ChildOutputT, ChildRenderingT> renderChild(
child: Workflow<ChildPropsT, ChildOutputT, ChildRenderingT>,
props: ChildPropsT,
key: String = "",
Expand Down Expand Up @@ -144,7 +144,7 @@ interface RenderContext<StateT, in OutputT : Any> {
* Convenience alias of [RenderContext.renderChild] for workflows that don't take props.
*/
/* ktlint-disable parameter-list-wrapping */
fun <StateT, OutputT : Any, ChildOutputT : Any, ChildRenderingT>
fun <StateT, OutputT, ChildOutputT, ChildRenderingT>
RenderContext<StateT, OutputT>.renderChild(
child: Workflow<Unit, ChildOutputT, ChildRenderingT>,
key: String = "",
Expand All @@ -157,7 +157,7 @@ fun <StateT, OutputT : Any, ChildOutputT : Any, ChildRenderingT>
* output.
*/
/* ktlint-disable parameter-list-wrapping */
fun <PropsT, StateT, OutputT : Any, ChildRenderingT>
fun <PropsT, StateT, OutputT, ChildRenderingT>
RenderContext<StateT, OutputT>.renderChild(
child: Workflow<PropsT, Nothing, ChildRenderingT>,
props: PropsT,
Expand All @@ -170,7 +170,7 @@ fun <PropsT, StateT, OutputT : Any, ChildRenderingT>
* output.
*/
/* ktlint-disable parameter-list-wrapping */
fun <StateT, OutputT : Any, ChildRenderingT>
fun <StateT, OutputT, ChildRenderingT>
RenderContext<StateT, OutputT>.renderChild(
child: Workflow<Unit, Nothing, ChildRenderingT>,
key: String = ""
Expand All @@ -185,7 +185,7 @@ fun <StateT, OutputT : Any, ChildRenderingT>
*
* @param key An optional string key that is used to distinguish between identical [Worker]s.
*/
fun <StateT, OutputT : Any> RenderContext<StateT, OutputT>.runningWorker(
fun <StateT, OutputT> RenderContext<StateT, OutputT>.runningWorker(
worker: Worker<Nothing>,
key: String = ""
) {
Expand All @@ -199,7 +199,7 @@ fun <StateT, OutputT : Any> RenderContext<StateT, OutputT>.runningWorker(
* Alternative to [RenderContext.actionSink] that allows externally defined
* event types to be mapped to anonymous [WorkflowAction]s.
*/
fun <EventT, StateT, OutputT : Any> RenderContext<StateT, OutputT>.makeEventSink(
fun <EventT, StateT, OutputT> RenderContext<StateT, OutputT>.makeEventSink(
update: Updater<StateT, OutputT>.(EventT) -> Unit
): Sink<EventT> = actionSink.contraMap { event ->
action({ "eventSink($event)" }) { update(event) }
Expand All @@ -216,7 +216,7 @@ fun <EventT, StateT, OutputT : Any> RenderContext<StateT, OutputT>.makeEventSink
"Use runningWorker",
ReplaceWith("runningWorker(worker, key, handler)", "com.squareup.workflow.runningWorker")
)
fun <StateT, OutputT : Any, T> RenderContext<StateT, OutputT>.onWorkerOutput(
fun <StateT, OutputT, T> RenderContext<StateT, OutputT>.onWorkerOutput(
worker: Worker<T>,
key: String = "",
handler: (T) -> WorkflowAction<StateT, OutputT>
Expand Down
4 changes: 2 additions & 2 deletions workflow-core/src/main/java/com/squareup/workflow/Sink.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fun <T1, T2> Sink<T1>.contraMap(transform: (T2) -> T1): Sink<T2> {
* ```
*/
@ExperimentalWorkflowApi
suspend fun <T, StateT, OutputT : Any> Flow<T>.collectToSink(
suspend fun <T, StateT, OutputT> Flow<T>.collectToSink(
actionSink: Sink<WorkflowAction<StateT, OutputT>>,
handler: (T) -> WorkflowAction<StateT, OutputT>
) {
Expand All @@ -93,7 +93,7 @@ suspend fun <T, StateT, OutputT : Any> Flow<T>.collectToSink(
* This method is intended to be used from [RenderContext.runningSideEffect].
*/
@ExperimentalWorkflowApi
suspend fun <StateT, OutputT : Any> Sink<WorkflowAction<StateT, OutputT>>.sendAndAwaitApplication(
suspend fun <StateT, OutputT> Sink<WorkflowAction<StateT, OutputT>>.sendAndAwaitApplication(
action: WorkflowAction<StateT, OutputT>
) {
suspendCancellableCoroutine<Unit> { continuation ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ import com.squareup.workflow.WorkflowAction.Updater
abstract class StatefulWorkflow<
in PropsT,
StateT,
out OutputT : Any,
out OutputT,
out RenderingT
> : Workflow<PropsT, OutputT, RenderingT> {

Expand Down Expand Up @@ -164,7 +164,7 @@ abstract class StatefulWorkflow<
/**
* Returns a stateful [Workflow] implemented via the given functions.
*/
inline fun <PropsT, StateT, OutputT : Any, RenderingT> Workflow.Companion.stateful(
inline fun <PropsT, StateT, OutputT, RenderingT> Workflow.Companion.stateful(
crossinline initialState: (PropsT, Snapshot?) -> StateT,
crossinline render: RenderContext<StateT, OutputT>.(props: PropsT, state: StateT) -> RenderingT,
crossinline snapshot: (StateT) -> Snapshot,
Expand Down Expand Up @@ -198,7 +198,7 @@ inline fun <PropsT, StateT, OutputT : Any, RenderingT> Workflow.Companion.statef
/**
* Returns a stateful [Workflow], with no props, implemented via the given functions.
*/
inline fun <StateT, OutputT : Any, RenderingT> Workflow.Companion.stateful(
inline fun <StateT, OutputT, RenderingT> Workflow.Companion.stateful(
crossinline initialState: (Snapshot?) -> StateT,
crossinline render: RenderContext<StateT, OutputT>.(state: StateT) -> RenderingT,
crossinline snapshot: (StateT) -> Snapshot
Expand All @@ -213,7 +213,7 @@ inline fun <StateT, OutputT : Any, RenderingT> Workflow.Companion.stateful(
*
* This overload does not support snapshotting, but there are other overloads that do.
*/
inline fun <PropsT, StateT, OutputT : Any, RenderingT> Workflow.Companion.stateful(
inline fun <PropsT, StateT, OutputT, RenderingT> Workflow.Companion.stateful(
crossinline initialState: (PropsT) -> StateT,
crossinline render: RenderContext<StateT, OutputT>.(props: PropsT, state: StateT) -> RenderingT,
crossinline onPropsChanged: (
Expand All @@ -233,7 +233,7 @@ inline fun <PropsT, StateT, OutputT : Any, RenderingT> Workflow.Companion.statef
*
* This overload does not support snapshots, but there are others that do.
*/
inline fun <StateT, OutputT : Any, RenderingT> Workflow.Companion.stateful(
inline fun <StateT, OutputT, RenderingT> Workflow.Companion.stateful(
initialState: StateT,
crossinline render: RenderContext<StateT, OutputT>.(state: StateT) -> RenderingT
): StatefulWorkflow<Unit, StateT, OutputT, RenderingT> = stateful(
Expand All @@ -249,7 +249,7 @@ inline fun <StateT, OutputT : Any, RenderingT> Workflow.Companion.stateful(
* @param name A string describing the update for debugging, included in [toString].
* @param update Function that defines the workflow update.
*/
fun <PropsT, StateT, OutputT : Any, RenderingT>
fun <PropsT, StateT, OutputT, RenderingT>
StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.action(
name: String = "",
update: Updater<StateT, OutputT>.() -> Unit
Expand All @@ -264,7 +264,7 @@ fun <PropsT, StateT, OutputT : Any, RenderingT>
* in [toString].
* @param update Function that defines the workflow update.
*/
fun <PropsT, StateT, OutputT : Any, RenderingT>
fun <PropsT, StateT, OutputT, RenderingT>
StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.action(
name: () -> String,
update: Updater<StateT, OutputT>.() -> Unit
Expand All @@ -280,7 +280,7 @@ fun <PropsT, StateT, OutputT : Any, RenderingT>
imports = arrayOf("com.squareup.workflow.action")
)
)
fun <PropsT, StateT, OutputT : Any, RenderingT>
fun <PropsT, StateT, OutputT, RenderingT>
StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.workflowAction(
name: String = "",
block: Mutator<StateT>.() -> OutputT?
Expand All @@ -294,7 +294,7 @@ fun <PropsT, StateT, OutputT : Any, RenderingT>
imports = arrayOf("com.squareup.workflow.action")
)
)
fun <PropsT, StateT, OutputT : Any, RenderingT>
fun <PropsT, StateT, OutputT, RenderingT>
StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.workflowAction(
name: () -> String,
block: Mutator<StateT>.() -> OutputT?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import com.squareup.workflow.WorkflowAction.Updater
*
* @see StatefulWorkflow
*/
abstract class StatelessWorkflow<in PropsT, out OutputT : Any, out RenderingT> :
abstract class StatelessWorkflow<in PropsT, out OutputT, out RenderingT> :
Workflow<PropsT, OutputT, RenderingT> {

@Suppress("UNCHECKED_CAST")
Expand Down Expand Up @@ -82,7 +82,7 @@ abstract class StatelessWorkflow<in PropsT, out OutputT : Any, out RenderingT> :
* [props][PropsT] received from its parent, and it may render child workflows that do have
* their own internal state.
*/
inline fun <PropsT, OutputT : Any, RenderingT> Workflow.Companion.stateless(
inline fun <PropsT, OutputT, RenderingT> Workflow.Companion.stateless(
crossinline render: RenderContext<Nothing, OutputT>.(props: PropsT) -> RenderingT
): Workflow<PropsT, OutputT, RenderingT> =
object : StatelessWorkflow<PropsT, OutputT, RenderingT>() {
Expand All @@ -108,7 +108,7 @@ fun <RenderingT> Workflow.Companion.rendering(
* @param name A string describing the update for debugging, included in [toString].
* @param update Function that defines the workflow update.
*/
fun <PropsT, OutputT : Any, RenderingT>
fun <PropsT, OutputT, RenderingT>
StatelessWorkflow<PropsT, OutputT, RenderingT>.action(
name: String = "",
update: Updater<Nothing, OutputT>.() -> Unit
Expand All @@ -123,7 +123,7 @@ fun <PropsT, OutputT : Any, RenderingT>
* [toString].
* @param update Function that defines the workflow update.
*/
fun <PropsT, OutputT : Any, RenderingT>
fun <PropsT, OutputT, RenderingT>
StatelessWorkflow<PropsT, OutputT, RenderingT>.action(
name: () -> String,
update: Updater<Nothing, OutputT>.() -> Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ interface Worker<out OutputT> {
* The returned [Worker] will equate to any other workers created with any of the [Worker]
* builder functions that have the same output type.
*/
inline fun <reified OutputT : Any> fromNullable(
inline fun <reified OutputT> fromNullable(
// This could be crossinline, but there's a coroutines bug that will cause the coroutine
// to immediately resume on suspension inside block when it is crossinline.
// See https://youtrack.jetbrains.com/issue/KT-31197.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ package com.squareup.workflow
* @see StatefulWorkflow
* @see StatelessWorkflow
*/
interface Workflow<in PropsT, out OutputT : Any, out RenderingT> {
interface Workflow<in PropsT, out OutputT, out RenderingT> {

/**
* Provides a [StatefulWorkflow] view of this workflow. Necessary because [StatefulWorkflow] is
Expand All @@ -125,7 +125,7 @@ interface Workflow<in PropsT, out OutputT : Any, out RenderingT> {
*/
/* ktlint-disable parameter-list-wrapping */
@OptIn(ExperimentalWorkflowApi::class)
fun <PropsT, OutputT : Any, FromRenderingT, ToRenderingT>
fun <PropsT, OutputT, FromRenderingT, ToRenderingT>
Workflow<PropsT, OutputT, FromRenderingT>.mapRendering(
transform: (FromRenderingT) -> ToRenderingT
): Workflow<PropsT, OutputT, ToRenderingT> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.squareup.workflow.WorkflowAction.Updater
/**
* An atomic operation that updates the state of a [Workflow], and also optionally emits an output.
*/
interface WorkflowAction<StateT, out OutputT : Any> {
interface WorkflowAction<StateT, out OutputT> {
@Deprecated("Use Updater")
class Mutator<S>(var state: S)

Expand All @@ -31,16 +31,22 @@ interface WorkflowAction<StateT, out OutputT : Any> {
*
* @param nextState the state that the workflow should move to. Default is the current state.
*/
class Updater<S, in O : Any>(var nextState: S) {
internal var output: @UnsafeVariance O? = null
class Updater<S, in O>(var nextState: S) {
private var output: @UnsafeVariance O? = null
private var isOutputSet = false

/**
* Sets the value the workflow will emit as output when this action is applied.
* If this method is not called, there will be no output.
*/
fun setOutput(output: O) {
this.output = output
isOutputSet = true
}

@Suppress("UNCHECKED_CAST")
internal fun <T : Any> mapOutput(mapper: (@UnsafeVariance O) -> T): T? =
if (isOutputSet) mapper(output as O) else null
}

/**
Expand Down Expand Up @@ -69,7 +75,7 @@ interface WorkflowAction<StateT, out OutputT : Any> {
* Use this to, for example, ignore the output of a child workflow or worker.
*/
@Suppress("UNCHECKED_CAST")
fun <StateT, OutputT : Any> noAction(): WorkflowAction<StateT, OutputT> =
fun <StateT, OutputT> noAction(): WorkflowAction<StateT, OutputT> =
NO_ACTION as WorkflowAction<StateT, OutputT>

/**
Expand All @@ -83,7 +89,7 @@ interface WorkflowAction<StateT, out OutputT : Any> {
imports = arrayOf("com.squareup.workflow.action")
)
)
fun <StateT, OutputT : Any> enterState(
fun <StateT, OutputT> enterState(
newState: StateT,
emittingOutput: OutputT? = null
): WorkflowAction<StateT, OutputT> =
Expand All @@ -103,7 +109,7 @@ interface WorkflowAction<StateT, out OutputT : Any> {
imports = arrayOf("com.squareup.workflow.action")
)
)
fun <StateT, OutputT : Any> enterState(
fun <StateT, OutputT> enterState(
name: String,
newState: StateT,
emittingOutput: OutputT? = null
Expand All @@ -123,7 +129,7 @@ interface WorkflowAction<StateT, out OutputT : Any> {
imports = arrayOf("com.squareup.workflow.action")
)
)
fun <StateT, OutputT : Any> modifyState(
fun <StateT, OutputT> modifyState(
name: () -> String,
emittingOutput: OutputT? = null,
modify: (StateT) -> StateT
Expand All @@ -143,7 +149,7 @@ interface WorkflowAction<StateT, out OutputT : Any> {
imports = arrayOf("com.squareup.workflow.action")
)
)
fun <StateT, OutputT : Any> emitOutput(output: OutputT): WorkflowAction<StateT, OutputT> =
fun <StateT, OutputT> emitOutput(output: OutputT): WorkflowAction<StateT, OutputT> =
action({ "emitOutput($output)" }) { setOutput(output) }

/**
Expand All @@ -156,7 +162,7 @@ interface WorkflowAction<StateT, out OutputT : Any> {
imports = arrayOf("com.squareup.workflow.action")
)
)
fun <StateT, OutputT : Any> emitOutput(
fun <StateT, OutputT> emitOutput(
name: String,
output: OutputT
): WorkflowAction<StateT, OutputT> =
Expand All @@ -179,7 +185,7 @@ interface WorkflowAction<StateT, out OutputT : Any> {
* @see StatelessWorkflow.action
* @see StatefulWorkflow.action
*/
inline fun <StateT, OutputT : Any> action(
inline fun <StateT, OutputT> action(
name: String = "",
crossinline apply: Updater<StateT, OutputT>.() -> Unit
) = action({ name }, apply)
Expand All @@ -197,18 +203,27 @@ inline fun <StateT, OutputT : Any> action(
* @see StatelessWorkflow.action
* @see StatefulWorkflow.action
*/
inline fun <StateT, OutputT : Any> action(
inline fun <StateT, OutputT> action(
crossinline name: () -> String,
crossinline apply: Updater<StateT, OutputT>.() -> Unit
): WorkflowAction<StateT, OutputT> = object : WorkflowAction<StateT, OutputT> {
override fun Updater<StateT, OutputT>.apply() = apply.invoke(this)
override fun toString(): String = "WorkflowAction(${name()})@${hashCode()}"
}

fun <StateT, OutputT : Any> WorkflowAction<StateT, OutputT>.applyTo(
state: StateT
): Pair<StateT, OutputT?> {
/**
* Applies this [WorkflowAction] to [state]. If the action sets an output, the output will be
* transformed by [mapOutput], and then both the new state and the transformed output will be
* returned.
*
* If the action sets the output multiple times, only the last one will be used.
*/
fun <StateT, OutputT, T : Any> WorkflowAction<StateT, OutputT>.applyTo(
state: StateT,
mapOutput: (OutputT) -> T
): Pair<StateT, T?> {
val updater = Updater<StateT, OutputT>(state)
updater.apply()
return Pair(updater.nextState, updater.output)
val output = updater.mapOutput(mapOutput)
return Pair(updater.nextState, output)
}
Loading