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

ciris.ConfigValue.scala Maven / Gradle / Ivy

There is a newer version: 0.12.1
Show newest version
package ciris

import ciris.api._
import ciris.api.syntax._

/**
  * [[ConfigValue]] represents the value part of a [[ConfigEntry]],
  * without any other details like the key, key type, or original
  * source value. [[ConfigEntry]] extends [[ConfigValue]], but
  * you can also create one with [[ConfigValue#apply]].
  *
  * @tparam F the context in which the value exists
  * @tparam V the type of the value
  */
abstract class ConfigValue[F[_]: Apply, V] {
  def value: F[Either[ConfigError, V]]

  /**
    * If the value of this [[ConfigValue]] is unavailable, tries to
    * use the value of that [[ConfigValue]], accumulating errors if
    * both values are unavailable.
*
* Note that the alternative value is passed by reference, and it * will only be evaluated if this [[ConfigValue]] is unavailable. * * @param that the [[ConfigValue]] to use if this value is unavailable * @tparam A the value type of that [[ConfigValue]] * @return a new [[ConfigValue]] * @example {{{ * scala> val combined = * | ConfigEntry[String, Int]("key", ConfigKeyType.Environment, Left(ConfigError("error1"))). * | orElse(ConfigEntry[String, Int]("key2", ConfigKeyType.Property, Left(ConfigError("error2")))) * combined: ConfigValue[api.Id, Int] = ConfigValue(Left(Combined(ConfigError(error1), ConfigError(error2)))) * * scala> combined.value.left.map(_.message).toString * res0: String = Left(Error1 and error2) * * scala> ConfigEntry[String, Int]("key", ConfigKeyType.Environment, Left(ConfigError("error1"))). * | orElse(ConfigEntry("key2", ConfigKeyType.Property, Right(123))) * res1: ConfigValue[api.Id, Int] = ConfigValue(Right(123)) * }}} */ final def orElse[A >: V](that: => ConfigValue[F, A])(implicit m: Monad[F]): ConfigValue[F, A] = ConfigValue.applyF[F, A] { this.value.flatMap { case right @ Right(_) => (right: Either[ConfigError, A]).pure[F] case Left(thisError) => that.value.map { case right @ Right(_) => right case Left(thatError) => Left(thisError combine thatError) } } } /** * If the value of this [[ConfigValue]] is available, wraps the * value in a `Some`; otherwise, uses `None` as the value, and * discards the [[ConfigError]]. This function is particularly * useful when combined with [[orElse]] as in the example. * * @return a new [[ConfigValue]] * @example {{{ * scala> env[String]("API_KEY"). * | orElse(prop[String]("api.key")). * | orNone * res0: ConfigValue[api.Id,Option[String]] = ConfigValue(Right(None)) * }}} */ final def orNone: ConfigValue[F, Option[V]] = ConfigValue.applyF[F, Option[V]] { this.value.map { case Right(v) => Right(Some(v)) case Left(_) => Right(None) } } private[ciris] final def append[A](next: ConfigValue[F, A]): ConfigValue2[F, V, A] = { new ConfigValue2((this.value product next.value).map { case (Right(v), Right(a)) => Right((v, a)) case (Left(error1), Right(_)) => Left(ConfigErrors(error1)) case (Right(_), Left(error2)) => Left(ConfigErrors(error2)) case (Left(error1), Left(error2)) => Left(error1 append error2) }) } } object ConfigValue { /** * Creates a new [[ConfigValue]] from the specified value. * * @param value the value or an error * @tparam V the type of the value * @return a new [[ConfigValue]] */ def apply[V](value: Either[ConfigError, V]): ConfigValue[Id, V] = ConfigValue.applyF[Id, V](value) /** * Creates a new [[ConfigValue]] from the specified value, * wrapped in context `F`, which can be [[api.Id]] if no * context is desired. [[ConfigValue#apply]] also exists * for the case when `F` is [[api.Id]]. * * @param value the value or an error, in context `F` * @tparam F the context in which the value exists * @tparam V the type of the value * @return a new [[ConfigValue]] */ def applyF[F[_]: Apply, V](value: F[Either[ConfigError, V]]): ConfigValue[F, V] = { val theValue = value new ConfigValue[F, V] { override def value: F[Either[ConfigError, V]] = theValue override def toString: String = s"ConfigValue($value)" } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy