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

zio.ZState.scala Maven / Gradle / Ivy

There is a newer version: 2.1.11
Show newest version
/*
 * Copyright 2021-2024 John A. De Goes and the ZIO Contributors
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package zio

import zio.stacktracer.TracingImplicits.disableAutoTrace

/**
 * `ZState[S]` models a value of type `S` that can be read from and written to
 * during the execution of an effect. The idiomatic way to work with `ZState` is
 * as part of the environment using operators defined on `ZIO`. For example:
 *
 * {{{
 * final case class MyState(counter: Int)
 *
 * for {
 *   _     <- ZIO.updateState[MyState](state => state.copy(counter = state.counter + 1))
 *   count <- ZIO.getStateWith[MyState](_.counter)
 * } yield count
 * }}}
 *
 * Because `ZState` is typically used as part of the environment, it is
 * recommended to define your own state type `S` such as `MyState` above rather
 * than using a type such as `Int` to avoid the risk of ambiguity.
 *
 * To run a stateful workflow, use the `ZIO.stateful` operator to allocate the
 * initial state.
 */
sealed trait ZState[S] {

  /**
   * Gets the current state.
   */
  def get(implicit trace: Trace): UIO[S]

  /**
   * Sets the state to the specified value.
   */
  def set(s: S)(implicit trace: Trace): UIO[Unit]

  /**
   * Updates the state with the specified function.
   */
  def update(f: S => S)(implicit trace: Trace): UIO[Unit]
}

object ZState {

  /**
   * A layer that allocates the initial state of a stateful workflow.
   */
  def initial[S: EnvironmentTag](s: => S)(implicit trace: Trace): ZLayer[Any, Nothing, ZState[S]] =
    initialPatch(s, Differ.update[S])

  /**
   * A layer that allocates the initial state of a stateful workflow, using the
   * specified patch type to combine updates to the state by different fibers in
   * a compositional way.
   */
  def initialPatch[State: EnvironmentTag, Patch](state: => State, differ: => Differ[State, Patch])(implicit
    trace: Trace
  ): ZLayer[Any, Nothing, ZState[State]] =
    ZLayer.scoped {
      for {
        fiberRef <- FiberRef.makePatch(state, differ)
      } yield new ZState[State] {
        def get(implicit trace: Trace): UIO[State] =
          fiberRef.get
        def set(state: State)(implicit trace: Trace): UIO[Unit] =
          fiberRef.set(state)
        def update(f: State => State)(implicit trace: Trace): UIO[Unit] =
          fiberRef.update(f)
      }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy