com.typesafe.config.ConfigValue Scala Examples

The following examples show how to use com.typesafe.config.ConfigValue. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: SeqShapedWriter.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.generic

import scala.collection.JavaConverters._

import com.typesafe.config.{ ConfigList, ConfigValue, ConfigValueFactory }
import pureconfig.{ ConfigWriter, Derivation }
import shapeless._


private[generic] trait SeqShapedWriter[Repr] extends ConfigWriter[Repr]

object SeqShapedWriter {

  implicit val hNilWriter: SeqShapedWriter[HNil] = new SeqShapedWriter[HNil] {
    override def to(v: HNil): ConfigValue = ConfigValueFactory.fromIterable(List().asJava)
  }

  implicit def hConsWriter[H, T <: HList](implicit hw: Derivation[Lazy[ConfigWriter[H]]], tw: Lazy[SeqShapedWriter[T]]): SeqShapedWriter[H :: T] =
    new SeqShapedWriter[H :: T] {
      override def to(v: H :: T): ConfigValue = {
        tw.value.to(v.tail) match {
          case cl: ConfigList =>
            ConfigValueFactory.fromIterable((hw.value.value.to(v.head) +: cl.asScala).asJava)
          case other =>
            throw new Exception(s"Unexpected value $other when trying to write a `ConfigValue` from an `HList`.")
        }
      }
    }
} 
Example 2
Source File: ModelConfigurationParser.scala    From modelmatrix   with Apache License 2.0 5 votes vote down vote up
package com.collective.modelmatrix

import java.nio.charset.CodingErrorAction
import java.security.MessageDigest
import java.util.function.BiConsumer

import com.typesafe.config.{Config, ConfigValue}

import scala.io.Codec
import scalaz.{Failure, Success, ValidationNel}

class ModelConfigurationParser(config: Config, path: String = "features") {

  type FeatureDefinition = (String, ValidationNel[String, ModelFeature])

  private lazy val configLines: Seq[(String, Int)] = {
    implicit val codec = Codec("UTF-8")
    codec.onMalformedInput(CodingErrorAction.REPLACE)
    codec.onUnmappableCharacter(CodingErrorAction.REPLACE)
    contentLines.zipWithIndex
  }

  // Try to find feature row index in original config if possible
  private def featureIndex(f: String): Int = {
    configLines.find(_._1.contains(f)).map(_._2).getOrElse(0)
  }

  private[this] val originUrl = config.origin().url()

  // configuration file as lines
  lazy val contentLines: Seq[String] = {
    if (originUrl != null) {
      scala.io.Source.fromURL(originUrl).getLines().toSeq
      // ideally this case below should never happen unless the Config passed in argument is not parsed from a file
    } else Seq.empty
  }

  // configuration file as a String
  lazy val content: String = contentLines.mkString(System.lineSeparator())

  // md5sum of the configuration content
  lazy val checksum: String = MessageDigest.getInstance("MD5").digest(content.getBytes).map("%02X".format(_)).mkString

  def features(): Seq[FeatureDefinition] = {
    val builder = collection.mutable.ListBuffer.empty[FeatureDefinition]

    config.getObject(path).forEach(new BiConsumer[String, ConfigValue] {
      def accept(t: String, u: ConfigValue): Unit = {
        val parsedFeature = ModelFeature.parse(t, u.atKey(t), t)
        builder += (t -> parsedFeature)
      }
    })

    builder.toSeq.sortBy {
      case (f, Success(feature)) => (true, featureIndex(feature.feature), feature.group, feature.feature)
      case (f, Failure(_)) => (false, featureIndex(f), "", f)
    }
  }
} 
Example 3
Source File: typesafe.scala    From tofu   with Apache License 2.0 5 votes vote down vote up
package tofu
package config

import ConfigItem._
import cats.Id
import com.typesafe.config.{Config, ConfigValue}

import scala.jdk.CollectionConverters._
import tofu.concurrent.Refs
import tofu.syntax.monadic._
import tofu.syntax.funk._
import cats.effect.SyncIO
import scala.collection.compat._

object typesafe {
  def fromConfig(cfg: Config): ConfigItem[Id] =
    fromValue(cfg.root())

  def fromValue(cfg: ConfigValue): ConfigItem[Id] =
    if (cfg == null) Null else fromUnwrapped(cfg.unwrapped())

  def fromUnwrapped(el: Any): ConfigItem[Id] =
    el match {
      case null                                   => Null
      case b: java.lang.Byte                      => Num(BigDecimal(b.intValue()))
      case s: java.lang.Short                     => Num(BigDecimal(s.intValue()))
      case i: Integer                             => Num(BigDecimal(i))
      case l: java.lang.Long                      => Num(BigDecimal(l))
      case bi: java.math.BigInteger               => Num(BigDecimal(bi))
      case bd: java.math.BigDecimal               => Num(BigDecimal(bd))
      case n: Number                              => Num(BigDecimal(n.doubleValue()))
      case b: java.lang.Boolean                   => Bool(b)
      case s: String                              => Str(s)
      case l: java.util.List[_]                   => seq(l.asScala.toVector.map(fromUnwrapped))
      case m: java.util.Map[String @unchecked, _] => dict(m.asScala.view.mapValues(fromUnwrapped).toMap)
    }

  def parseValue[F[_]: Refs: MonadThrow: ParallelReader, A: Configurable](cfg: ConfigValue): F[A] =
    fromValue(cfg).mapK[F](makeFunctionK(_.pure[F])).parseSync[A]

  def parseCfg[F[_]: Refs: MonadThrow: ParallelReader, A: Configurable](cfg: Config): F[A] = parseValue(cfg.root())

  def syncParseValue[A: Configurable](cfg: ConfigValue): Either[MessageList, A] =
    parseValue[SyncIO, A](cfg).attempt.flatMap {
      case Left(ConfigParseErrors(list)) => Left(list).pure[SyncIO]
      case Left(ex)                      => SyncIO.raiseError(ex)
      case Right(a)                      => Right(a).pure[SyncIO]
    }.unsafeRunSync()

  def syncParseConfig[A: Configurable](cfg: Config): Either[MessageList, A] = syncParseValue(cfg.root())
} 
Example 4
Source File: EmailNotifierConfig.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package vinyldns.api.notifier.email

import scala.collection.JavaConverters._
import javax.mail.Address
import javax.mail.internet.InternetAddress
import pureconfig.ConfigReader
import scala.util.Try
import pureconfig.error.CannotConvert
import java.util.Properties
import com.typesafe.config.{ConfigObject, ConfigValue}
import com.typesafe.config.ConfigValueType

object EmailNotifierConfig {

  implicit val smtpPropertiesReader: ConfigReader[Properties] = {
    ConfigReader[ConfigObject].map { config =>
      val props = new Properties()

      def convertToProperties(baseKey: String, config: ConfigObject): Unit =
        config.keySet().asScala.foreach {
          case key =>
            config.get(key) match {
              case value: ConfigObject =>
                convertToProperties(s"${baseKey}.${key}", value)
              case value: ConfigValue if value.valueType != ConfigValueType.NULL =>
                props.put(s"${baseKey}.${key}", value.unwrapped())
              case _ =>
            }
        }

      convertToProperties("mail.smtp", config)
      props
    }
  }

  implicit val addressReader: ConfigReader[Address] = ConfigReader[String].emap { s =>
    Try(new InternetAddress(s)).toEither.left.map { exc =>
      CannotConvert(s, "InternetAddress", exc.getMessage)
    }
  }

}

case class EmailNotifierConfig(from: Address, smtp: Properties = new Properties()) 
Example 5
Source File: ParamParser.scala    From DataQuality   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package dbmodel.config

import com.typesafe.config.{ConfigValue, ConfigValueFactory}

import scala.collection.JavaConversions._
import scala.util.matching.Regex.MatchIterator


object ParamParser {

  def parseParam(string: String): ConfigValue = {
    val regex = "\\[.*\\]".r

    string match {
      case regex() =>
        val r = """(?:\.,|#)?\w+""".r
        val matches: MatchIterator = r findAllIn string
        ConfigValueFactory.fromIterable(matches.toSeq)
      case _ =>
        ConfigValueFactory.fromAnyRef(string)
    }
  }

  def unquote(string: String): String = {
    val regex = "\".*\"".r
    string match {
      case regex() => string.substring(1, string.length-1)
      case _ => string
    }
  }

} 
Example 6
Source File: ParamParser.scala    From DataQuality   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package models.config

import com.typesafe.config.{ConfigValue, ConfigValueFactory}

import scala.collection.JavaConversions._
import scala.util.matching.Regex.MatchIterator


object ParamParser {

  def parseParam(string: String): ConfigValue = {
    val regex = "\\[.*\\]".r

    string match {
      case regex() =>
        val r = """(?:\.,|#)?\w+""".r
        val matches: MatchIterator = r findAllIn string
        ConfigValueFactory.fromIterable(matches.toSeq)
      case _ =>
        ConfigValueFactory.fromAnyRef(string)
    }
  }

  def unquote(string: String): String = {
    val regex = "\".*\"".r
    string match {
      case regex() => string.substring(1, string.length-1)
      case _ => string
    }
  }

} 
Example 7
Source File: ConfigUtils.scala    From Raphtory   with Apache License 2.0 5 votes vote down vote up
package com.raphtory.core.clustersetup.util

import com.typesafe.config.Config
import com.typesafe.config.ConfigValue

import scala.collection.JavaConversions._

object ConfigUtils {

  case class SocketAddress(host: String, port: String)

  case class SystemConfig(
      bindAddress: SocketAddress,
      tcpAddress: SocketAddress,
      seeds: List[ConfigValue],
      roles: List[ConfigValue]
  )

  implicit class ConfigParser(config: Config) {
    def parse(): SystemConfig = {
      val bindHost    = config.getString("akka.remote.netty.tcp.bind-hostname")
      val bindPort    = config.getString("akka.remote.netty.tcp.bind-port")
      val bindAddress = SocketAddress(bindHost, bindPort)

      val tcpHost    = config.getString("akka.remote.netty.tcp.hostname")
      val tcpPort    = config.getString("akka.remote.netty.tcp.port")
      val tcpAddress = SocketAddress(tcpHost, tcpPort)

      val seeds = config.getList("akka.cluster.seed-nodes").toList
      val roles = config.getList("akka.cluster.roles").toList

      SystemConfig(bindAddress = bindAddress, tcpAddress = tcpAddress, seeds, roles)
    }
  }
} 
Example 8
Source File: ConfigReaderSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig

import com.typesafe.config.{ ConfigFactory, ConfigObject, ConfigOriginFactory, ConfigParseOptions, ConfigValue, ConfigValueFactory }
import org.scalacheck.{ Arbitrary, Gen }
import pureconfig.error._

class ConfigReaderSuite extends BaseSuite {
  implicit override val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 100)

  val intReader = ConfigReader[Int]
  val strReader = ConfigReader[String]

  def intSummedReader(n: Int) = new ConfigReader[Int] {
    def from(cur: ConfigCursor) = intReader.from(cur).right.map(_ + n)
  }

  // generate configs that always read correctly as strings, but not always as integers
  val genConfig: Gen[ConfigValue] =
    Gen.frequency(80 -> Gen.chooseNum(Int.MinValue, Int.MaxValue), 20 -> Gen.alphaStr)
      .map(ConfigValueFactory.fromAnyRef)

  val genFailureReason: Gen[FailureReason] =
    Gen.const(UnknownKey(""))

  implicit val arbConfig = Arbitrary(genConfig)
  implicit val arbFailureReason = Arbitrary(genFailureReason)

  behavior of "ConfigReader"

  it should "have a correct map method" in forAll { (conf: ConfigValue, f: Int => String) =>
    intReader.map(f).from(conf) shouldEqual intReader.from(conf).right.map(f)
  }

  it should "have a map method that wraps exceptions in a ConfigReaderFailure" in {
    val throwable = new Exception("Exception message.")
    val cr = ConfigReader[Int].map({ _ => throw throwable })
    cr.from(ConfigValueFactory.fromAnyRef(1)) should failWith(ExceptionThrown(throwable))
  }

  it should "have a correct emap method" in forAll { (conf: ConfigValue, f: Int => Either[FailureReason, String]) =>
    def getReason[A](failures: ConfigReaderFailures): FailureReason = failures match {
      case ConfigReaderFailures(ConvertFailure(reason, _, _)) => reason
      case _ => throw new Exception(s"Unexpected value: $failures")
    }
    intReader.emap(f).from(conf).left.map(getReason) shouldEqual
      intReader.from(conf).left.map(getReason).right.flatMap(f)
  }

  it should "have a correct flatMap method" in forAll { conf: ConfigValue =>
    val g: Int => ConfigReader[Int] = intSummedReader
    intReader.flatMap(g).from(conf) shouldEqual intReader.from(conf).right.flatMap(g(_).from(conf))
  }

  it should "have a correct zip method" in forAll { conf: ConfigValue =>
    def zip[A, B](r1: ConfigReader[A], r2: ConfigReader[B]): ConfigReader.Result[(A, B)] = {
      (r1.from(conf), r2.from(conf)) match {
        case (Right(a), Right(b)) => Right((a, b))
        case (Left(fa), Right(_)) => Left(fa)
        case (Right(_), Left(fb)) => Left(fb)
        case (Left(fa), Left(fb)) => Left(fa ++ fb)
      }
    }

    intReader.zip(strReader).from(conf) shouldEqual zip(intReader, strReader)
    strReader.zip(intReader).from(conf) shouldEqual zip(strReader, intReader)
    intReader.zip(intReader).from(conf) shouldEqual zip(intReader, intReader)
    strReader.zip(strReader).from(conf) shouldEqual zip(strReader, strReader)
  }

  it should "have a correct orElse method" in forAll { conf: ConfigValue =>
    def orElse[AA, A <: AA, B <: AA](r1: ConfigReader[A], r2: ConfigReader[B]): ConfigReader.Result[AA] = {
      (r1.from(conf), r2.from(conf)) match {
        case (Right(a), _) => Right(a)
        case (Left(_), Right(b)) => Right(b)
        case (Left(fa), Left(fb)) => Left(fa ++ fb)
      }
    }

    // results are explicitly typed so that we also test the resulting type of `orElse`
    intReader.orElse(strReader).from(conf) shouldEqual orElse[Any, Int, String](intReader, strReader)
    strReader.orElse(intReader).from(conf) shouldEqual orElse[Any, String, Int](strReader, intReader)
    intReader.orElse(intReader).from(conf) shouldEqual orElse[Int, Int, Int](intReader, intReader)
    strReader.orElse(strReader).from(conf) shouldEqual orElse[String, String, String](strReader, strReader)
  }

  it should "have a correct contramapConfig method" in forAll { conf: ConfigValue =>
    val wrappedConf = conf.atKey("value").root()
    val unwrap = { cv: ConfigValue => cv.asInstanceOf[ConfigObject].get("value") }

    intReader.contramapConfig(unwrap).from(wrappedConf) shouldEqual intReader.from(conf)
  }
} 
Example 9
Source File: ConfigConvertSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig

import com.typesafe.config.{ ConfigValue, ConfigValueFactory, ConfigValueType }
import org.scalacheck.{ Arbitrary, Gen }
import pureconfig.error.{ ExceptionThrown, WrongType, CannotConvert }
import ConfigConvertSuite._

class ConfigConvertSuite extends BaseSuite {
  implicit override val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 100)

  val intConvert = ConfigConvert[Int]

  // generate configs that always read correctly as strings, but not always as integers
  val genConfig: Gen[ConfigValue] =
    Gen.frequency(80 -> Gen.chooseNum(Int.MinValue, Int.MaxValue), 20 -> Gen.alphaStr)
      .map(ConfigValueFactory.fromAnyRef)

  implicit val arbConfig = Arbitrary(genConfig)

  behavior of "ConfigConvert"

  it should "have a correct xmap method" in forAll { (f: Int => String, g: String => Int) =>
    forAll { str: String => intConvert.xmap(f, g).to(str) shouldEqual intConvert.to(g(str)) }
    forAll { conf: ConfigValue => intConvert.xmap(f, g).from(conf) shouldEqual intConvert.from(conf).right.map(f) }
  }

  it should "have a xmap method that wraps exceptions in a ConfigReaderFailure" in {
    val throwable = new Exception("Exception message.")
    val cc = ConfigConvert[Int].xmap[String]({ _ => throw throwable }, { _: String => 42 })
    cc.from(ConfigValueFactory.fromAnyRef(1)) should failWith(
      ExceptionThrown(throwable))
    cc.from(ConfigValueFactory.fromAnyRef("test")) should failWith(
      WrongType(ConfigValueType.STRING, Set(ConfigValueType.NUMBER)))
  }

  it should "have a xemap method that allows specifying custom failure messages" in {
    ConfigConvert[EvenInt].from(ConfigValueFactory.fromAnyRef(1)) should
      failWith(CannotConvert("1", "EvenInt", EvenInt.err(1)))
  }

  it should "correctly read using xemap" in {
    ConfigConvert[EvenInt].from(ConfigValueFactory.fromAnyRef(2)) shouldEqual Right(EvenInt(2))
  }
}

object ConfigConvertSuite {
  case class EvenInt(i: Int) extends AnyVal
  object EvenInt {
    def err(i: Int): String = s"Cannot construct an EvenInt from $i because it's not even"

    def safely(i: Int): Either[String, EvenInt] =
      if (i % 2 == 0) Right(EvenInt(i)) else Left(err(i))

    implicit val configConvert: ConfigConvert[EvenInt] =
      ConfigConvert[Int].xemap(
        i => safely(i).left.map(s => CannotConvert(i.toString, "EvenInt", s)),
        _.i)
  }
} 
Example 10
Source File: package.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.cats

import scala.collection.JavaConverters._

import com.typesafe.config.{ Config, ConfigValue, ConfigValueFactory }
import org.scalacheck.Arbitrary.{ arbitrary => arb }
import org.scalacheck.{ Arbitrary, Cogen, Gen }
import pureconfig._
import pureconfig.error.{ ConfigReaderFailures, ConvertFailure }

package object arbitrary {

  private[this] val MaxConfigDepth = 3
  private[this] val MaxCollSize = 3

  private[this] def genAnyMapForConfig(maxDepth: Int): Gen[Map[String, Any]] = {
    Gen.choose(0, MaxCollSize).flatMap { sz =>
      Gen.mapOfN(sz, for { k <- Gen.alphaStr; v <- Gen.lzy(genAnyForConfig(maxDepth - 1)) } yield (k, v))
    }
  }

  private[this] def genAnyForConfig(maxDepth: Int): Gen[Any] = {
    val genScalar: Gen[Any] = Gen.oneOf(
      Gen.oneOf(true, false),
      Gen.choose(Int.MinValue, Int.MaxValue),
      Gen.choose(Double.MinValue, Double.MaxValue),
      Gen.alphaStr)

    def genList(maxDepth: Int): Gen[List[Any]] = Gen.choose(0, MaxCollSize).flatMap { sz =>
      Gen.listOfN(sz, Gen.lzy(genAnyForConfig(maxDepth - 1)))
    }

    if (maxDepth == 0) genScalar
    else Gen.frequency(
      3 -> genScalar,
      1 -> genList(maxDepth).map(_.asJava),
      1 -> genAnyMapForConfig(maxDepth).map(_.asJava))
  }

  implicit val arbConfigValue: Arbitrary[ConfigValue] = Arbitrary {
    genAnyForConfig(MaxConfigDepth).map(ConfigValueFactory.fromAnyRef)
  }

  implicit val arbConfig: Arbitrary[Config] = Arbitrary {
    genAnyMapForConfig(MaxConfigDepth).map(_.asJava).map(ConfigValueFactory.fromMap(_).toConfig)
  }

  implicit val cogenConfigValue: Cogen[ConfigValue] =
    Cogen[String].contramap[ConfigValue](_.render)

  implicit val arbConfigReaderFailures: Arbitrary[ConfigReaderFailures] = Arbitrary {
    Gen.const(ConfigReaderFailures(ConvertFailure(EmptyTraversableFound("List"), None, "")))
  }

  implicit val cogenConfigReaderFailures: Cogen[ConfigReaderFailures] =
    Cogen[String].contramap[ConfigReaderFailures](_.toString)

  implicit val arbConfigObjectSource: Arbitrary[ConfigObjectSource] = Arbitrary {
    Gen.either(arb[ConfigReaderFailures], arb[Config]).map(ConfigObjectSource(_))
  }

  implicit def arbConfigReader[A: Arbitrary]: Arbitrary[ConfigReader[A]] = Arbitrary {
    arb[ConfigValue => ConfigReader.Result[A]].map(ConfigReader.fromFunction)
  }

  implicit def arbConfigWriter[A: Cogen]: Arbitrary[ConfigWriter[A]] = Arbitrary {
    arb[A => ConfigValue].map(ConfigWriter.fromFunction)
  }

  implicit def arbConfigConvert[A: Arbitrary: Cogen]: Arbitrary[ConfigConvert[A]] = Arbitrary {
    for { reader <- arb[ConfigReader[A]]; writer <- arb[ConfigWriter[A]] }
      yield ConfigConvert.fromReaderAndWriter(Derivation.Successful(reader), Derivation.Successful(writer))
  }
} 
Example 11
Source File: package.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.cats

import cats.Eq
import cats.kernel.instances.either._
import cats.kernel.instances.tuple._
import com.typesafe.config.ConfigValue
import org.scalacheck.Arbitrary
import pureconfig._
import pureconfig.module.cats.arbitrary._
import pureconfig.module.cats.instances._

package object eq {

  // This is the old implementation (pre-2.0.0) of Eq for functions in Cats. The new implementation requires an instance
  // of ExhaustiveCheck (see https://github.com/typelevel/cats/pull/2577), which we are unable to provide for the types
  // we use in tests. For our use case, it's OK to go with Arbitrary values.
  private implicit def catsLawsEqForFn1[A, B](implicit A: Arbitrary[A], B: Eq[B]): Eq[A => B] = new Eq[A => B] {
    val sampleCnt: Int = 50

    def eqv(f: A => B, g: A => B): Boolean = {
      val samples = List.fill(sampleCnt)(A.arbitrary.sample).collect {
        case Some(a) => a
        case None => sys.error("Could not generate arbitrary values to compare two functions")
      }
      samples.forall(s => B.eqv(f(s), g(s)))
    }
  }

  implicit def configReaderEq[A: Eq]: Eq[ConfigReader[A]] =
    Eq.by[ConfigReader[A], ConfigValue => ConfigReader.Result[A]](_.from)

  implicit def configWriterEq[A: Arbitrary]: Eq[ConfigWriter[A]] =
    Eq.by[ConfigWriter[A], A => ConfigValue](_.to)

  implicit def configConvertEq[A: Eq: Arbitrary]: Eq[ConfigConvert[A]] =
    Eq.by[ConfigConvert[A], (ConfigReader[A], ConfigWriter[A])] { cc => (cc, cc) }

  implicit val configObjectSourceEq: Eq[ConfigObjectSource] =
    Eq.by { cs => cs.config() }
} 
Example 12
Source File: package.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.cats

import cats._
import com.typesafe.config.{ Config, ConfigFactory, ConfigValue }
import pureconfig._
import pureconfig.error.{ ConfigReaderFailure, ConfigReaderFailures }

package object instances {

  implicit val configReaderInstance: ApplicativeError[ConfigReader, ConfigReaderFailures] =
    new ApplicativeError[ConfigReader, ConfigReaderFailures] {
      def pure[A](x: A): ConfigReader[A] =
        ConfigReader.fromFunction { _ => Right(x) }

      def ap[A, B](ff: ConfigReader[A => B])(fa: ConfigReader[A]): ConfigReader[B] =
        ff.zip(fa).map { case (f, a) => f(a) }

      def raiseError[A](e: ConfigReaderFailures): ConfigReader[A] =
        ConfigReader.fromFunction { _ => Left(e) }

      def handleErrorWith[A](fa: ConfigReader[A])(f: ConfigReaderFailures => ConfigReader[A]): ConfigReader[A] =
        ConfigReader.fromFunction { cv =>
          fa.from(cv) match {
            case Left(failures) => f(failures).from(cv)
            case r @ Right(_) => r
          }
        }
    }

  implicit val configWriterCatsInstance: ContravariantSemigroupal[ConfigWriter] =
    new ContravariantSemigroupal[ConfigWriter] {
      def contramap[A, B](fa: ConfigWriter[A])(f: B => A): ConfigWriter[B] =
        fa.contramap(f)

      def product[A, B](fa: ConfigWriter[A], fb: ConfigWriter[B]) =
        ConfigWriter.fromFunction[(A, B)] {
          case (a, b) =>
            fb.to(b).withFallback(fa.to(a))
        }
    }

  implicit val configConvertCatsInstance: InvariantSemigroupal[ConfigConvert] =
    new InvariantSemigroupal[ConfigConvert] {
      def imap[A, B](fa: ConfigConvert[A])(f: A => B)(g: B => A): ConfigConvert[B] =
        fa.xmap(f, g)

      def product[A, B](fa: ConfigConvert[A], fb: ConfigConvert[B]): ConfigConvert[(A, B)] = {
        val reader = fa.zip(fb)
        val writer = ConfigWriter.fromFunction[(A, B)] {
          case (a, b) =>
            fb.to(b).withFallback(fa.to(a))
        }

        ConfigConvert.fromReaderAndWriter(
          Derivation.Successful(reader),
          Derivation.Successful(writer))
      }
    }

  implicit val configValueEq: Eq[ConfigValue] = Eq.fromUniversalEquals
  implicit val configEq: Eq[Config] = Eq.fromUniversalEquals
  implicit val configReaderFailureEq: Eq[ConfigReaderFailure] = Eq.fromUniversalEquals
  implicit val configReaderFailuresEq: Eq[ConfigReaderFailures] = Eq.fromUniversalEquals

  implicit val configReaderFailuresSemigroup: Semigroup[ConfigReaderFailures] =
    Semigroup.instance(_ ++ _)

  implicit val configValueCatsSemigroup: Semigroup[ConfigValue] =
    Semigroup.instance((a, b) => b.withFallback(a))

  implicit val configCatsMonoid: Monoid[Config] =
    Monoid.instance(ConfigFactory.empty, (a, b) => b.withFallback(a))

  implicit val configObjectSourceCatsMonoid: Monoid[ConfigObjectSource] =
    Monoid.instance(ConfigSource.empty, (a, b) => b.withFallback(a))
} 
Example 13
Source File: NoValidCoproductOptionFound.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.generic.error

import com.typesafe.config.{ ConfigRenderOptions, ConfigValue }
import pureconfig.error.{ ConfigReaderFailures, FailureReason }


final case class NoValidCoproductOptionFound(value: ConfigValue, optionFailures: Seq[(String, ConfigReaderFailures)]) extends FailureReason {
  def description = {
    val baseDescription = s"No valid coproduct option found for '${value.render(ConfigRenderOptions.concise())}'."
    baseDescription + (
      if (optionFailures.isEmpty) ""
      else {
        "\n" + optionFailures.map {
          case (optionName, failures) =>
            s"Can't use coproduct option '$optionName':\n" + failures.prettyPrint(1)
        }.mkString("\n")
      })
  }
} 
Example 14
Source File: MapShapedWriter.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.generic

import scala.collection.JavaConverters._

import com.typesafe.config.{ ConfigFactory, ConfigObject, ConfigValue }
import pureconfig._
import shapeless._
import shapeless.labelled.FieldType


private[generic] trait MapShapedWriter[Original, Repr] extends ConfigWriter[Repr]

object MapShapedWriter {

  implicit def labelledHNilWriter[Original]: MapShapedWriter[Original, HNil] = new MapShapedWriter[Original, HNil] {
    override def to(t: HNil): ConfigValue = ConfigFactory.parseMap(Map().asJava).root()
  }

  final implicit def labelledHConsWriter[Original, K <: Symbol, H, T <: HList](
    implicit
    key: Witness.Aux[K],
    hConfigWriter: Derivation[Lazy[ConfigWriter[H]]],
    tConfigWriter: Lazy[MapShapedWriter[Original, T]],
    hint: ProductHint[Original]): MapShapedWriter[Original, FieldType[K, H] :: T] =
    new MapShapedWriter[Original, FieldType[K, H] :: T] {
      override def to(t: FieldType[K, H] :: T): ConfigValue = {
        val rem = tConfigWriter.value.to(t.tail)
        val valueOpt = hConfigWriter.value.value match {
          case tc: WritesMissingKeys[H @unchecked] =>
            tc.toOpt(t.head)
          case w =>
            Some(w.to(t.head))
        }
        val kv = hint.to(valueOpt, key.value.name)

        // TODO check that all keys are unique
        kv.fold(rem) {
          case (k, v) =>
            rem.asInstanceOf[ConfigObject].withValue(k, v)
        }
      }
    }
} 
Example 15
Source File: package.scala    From refined   with MIT License 5 votes vote down vote up
package eu.timepit.refined

import _root_.pureconfig.{ConfigConvert, ConfigCursor}
import _root_.pureconfig.error.{CannotConvert, ConfigReaderFailures, ConvertFailure}
import com.typesafe.config.ConfigValue
import eu.timepit.refined.api.{RefType, Validate}
import scala.reflect.runtime.universe.WeakTypeTag

package object pureconfig {

  implicit def refTypeConfigConvert[F[_, _], T, P](
      implicit configConvert: ConfigConvert[T],
      refType: RefType[F],
      validate: Validate[T, P],
      typeTag: WeakTypeTag[F[T, P]]
  ): ConfigConvert[F[T, P]] = new ConfigConvert[F[T, P]] {
    override def from(cur: ConfigCursor): Either[ConfigReaderFailures, F[T, P]] =
      configConvert.from(cur) match {
        case Right(t) =>
          refType.refine[P](t) match {
            case Left(because) =>
              Left(
                ConfigReaderFailures(
                  ConvertFailure(
                    reason = CannotConvert(
                      value = cur.value.render(),
                      toType = typeTag.tpe.toString,
                      because = because
                    ),
                    cur = cur
                  )
                )
              )

            case Right(refined) =>
              Right(refined)
          }

        case Left(configReaderFailures) =>
          Left(configReaderFailures)
      }

    override def to(t: F[T, P]): ConfigValue =
      configConvert.to(refType.unwrap(t))
  }
} 
Example 16
Source File: EnumCoproductHint.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.generic

import com.typesafe.config.{ ConfigObject, ConfigValue, ConfigValueType }
import pureconfig._
import pureconfig.error._
import pureconfig.generic.CoproductHint.Use
import pureconfig.generic.error.{ CoproductHintException, NoValidCoproductOptionFound }
import pureconfig.syntax._


  protected def fieldValue(name: String): String = name.toLowerCase

  def from(cursor: ConfigCursor, options: Seq[String]): ConfigReader.Result[CoproductHint.Action] =
    cursor.asString.right.flatMap { str =>
      options.find(str == fieldValue(_)) match {
        case Some(opt) => Right(Use(cursor, opt))
        case None => cursor.failed[CoproductHint.Action](NoValidCoproductOptionFound(cursor.value, Seq.empty))
      }
    }

  def to(value: ConfigValue, name: String): ConfigValue =
    value match {
      case co: ConfigObject if co.isEmpty => fieldValue(name).toConfig
      case _: ConfigObject =>
        throw CoproductHintException(NonEmptyObjectFound(name))
      case cv =>
        throw CoproductHintException(WrongType(cv.valueType, Set(ConfigValueType.OBJECT)))
    }
} 
Example 17
Source File: EnumerationConfigWriterBuilder.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.generic

import com.typesafe.config.{ ConfigValue, ConfigValueFactory }
import pureconfig.ConfigWriter
import shapeless._
import shapeless.labelled._


trait EnumerationConfigWriterBuilder[A] {
  def build(transformName: String => String): ConfigWriter[A]
}

object EnumerationConfigWriterBuilder {
  implicit val deriveEnumerationWriterBuilderCNil: EnumerationConfigWriterBuilder[CNil] =
    new EnumerationConfigWriterBuilder[CNil] {
      def build(transformName: String => String): ConfigWriter[CNil] =
        new ConfigWriter[CNil] {
          def to(a: CNil): ConfigValue =
            throw new IllegalStateException("Cannot encode CNil. This is likely a bug in PureConfig.")
        }
    }

  implicit def deriveEnumerationWriterBuilderCCons[K <: Symbol, H, T <: Coproduct](
    implicit
    vName: Witness.Aux[K],
    hGen: LabelledGeneric.Aux[H, HNil],
    tWriterBuilder: EnumerationConfigWriterBuilder[T]): EnumerationConfigWriterBuilder[FieldType[K, H] :+: T] =
    new EnumerationConfigWriterBuilder[FieldType[K, H] :+: T] {
      def build(transformName: String => String): ConfigWriter[FieldType[K, H] :+: T] = {
        lazy val tWriter = tWriterBuilder.build(transformName)
        new ConfigWriter[FieldType[K, H] :+: T] {
          def to(a: FieldType[K, H] :+: T): ConfigValue = a match {
            case Inl(_) => ConfigValueFactory.fromAnyRef(transformName(vName.value.name))
            case Inr(r) => tWriter.to(r)
          }
        }
      }
    }

  implicit def deriveEnumerationWriterBuilder[A, Repr <: Coproduct](
    implicit
    gen: LabelledGeneric.Aux[A, Repr],
    reprWriterBuilder: EnumerationConfigWriterBuilder[Repr]): EnumerationConfigWriterBuilder[A] =
    new EnumerationConfigWriterBuilder[A] {
      def build(transformName: String => String): ConfigWriter[A] = {
        reprWriterBuilder.build(transformName).contramap(gen.to)
      }
    }
} 
Example 18
Source File: CoproductConfigWriter.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.generic

import com.typesafe.config.ConfigValue
import pureconfig.{ ConfigWriter, Derivation }
import shapeless.labelled._
import shapeless._


private[generic] trait CoproductConfigWriter[Original, Repr <: Coproduct] extends ConfigWriter[Repr]

object CoproductConfigWriter {
  final implicit def cNilWriter[Original]: CoproductConfigWriter[Original, CNil] = new CoproductConfigWriter[Original, CNil] {
    override def to(t: CNil): ConfigValue =
      throw new IllegalStateException("Cannot encode CNil. This is likely a bug in PureConfig.")
  }

  final implicit def cConsWriter[Original, Name <: Symbol, V <: Original, T <: Coproduct](
    implicit
    coproductHint: CoproductHint[Original],
    vName: Witness.Aux[Name],
    vConfigWriter: Derivation[Lazy[ConfigWriter[V]]],
    tConfigWriter: Lazy[CoproductConfigWriter[Original, T]]): CoproductConfigWriter[Original, FieldType[Name, V] :+: T] =
    new CoproductConfigWriter[Original, FieldType[Name, V] :+: T] {
      override def to(t: FieldType[Name, V] :+: T): ConfigValue = t match {
        case Inl(l) =>
          coproductHint.to(vConfigWriter.value.value.to(l), vName.value.name)

        case Inr(r) =>
          tConfigWriter.value.to(r)
      }
    }
} 
Example 19
Source File: MagnoliaConfigWriter.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.magnolia

import scala.collection.JavaConverters._
import scala.reflect.ClassTag

import _root_.magnolia._
import com.typesafe.config.{ ConfigValue, ConfigValueFactory }
import pureconfig._
import pureconfig.generic.{ CoproductHint, ProductHint }


object MagnoliaConfigWriter {

  def combine[A](ctx: CaseClass[ConfigWriter, A])(implicit hint: ProductHint[A]): ConfigWriter[A] =
    if (ctx.typeName.full.startsWith("scala.Tuple")) combineTuple(ctx)
    else if (ctx.isValueClass) combineValueClass(ctx)
    else combineCaseClass(ctx)

  private def combineCaseClass[A](ctx: CaseClass[ConfigWriter, A])(implicit hint: ProductHint[A]): ConfigWriter[A] = new ConfigWriter[A] {
    def to(a: A): ConfigValue = {
      val fieldValues = ctx.parameters.map { param =>
        val valueOpt = param.typeclass match {
          case tc: WritesMissingKeys[param.PType @unchecked] =>
            tc.toOpt(param.dereference(a))
          case tc =>
            Some(tc.to(param.dereference(a)))
        }
        hint.to(valueOpt, param.label)
      }
      ConfigValueFactory.fromMap(fieldValues.flatten.toMap.asJava)
    }
  }

  private def combineTuple[A](ctx: CaseClass[ConfigWriter, A]): ConfigWriter[A] = new ConfigWriter[A] {
    override def to(a: A): ConfigValue = ConfigValueFactory.fromIterable(
      ctx.parameters.map { param => param.typeclass.to(param.dereference(a)) }.asJava)
  }

  private def combineValueClass[A](ctx: CaseClass[ConfigWriter, A]): ConfigWriter[A] = new ConfigWriter[A] {
    override def to(a: A): ConfigValue =
      ctx.parameters.map { param => param.typeclass.to(param.dereference(a)) }.head
  }

  def dispatch[A: ClassTag](ctx: SealedTrait[ConfigWriter, A])(implicit hint: CoproductHint[A]): ConfigWriter[A] = new ConfigWriter[A] {
    def to(a: A): ConfigValue = ctx.dispatch(a) { subtype =>
      hint.to(subtype.typeclass.to(subtype.cast(a)), subtype.typeName.short)
    }
  }
} 
Example 20
Source File: ScalazLawsSuite.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.scalaz

import com.typesafe.config.ConfigValue
import org.scalacheck.{ Prop, Properties }
import org.scalatest.funsuite.AnyFunSuite
import org.scalatestplus.scalacheck.Checkers
import pureconfig.error.ConfigReaderFailures
import pureconfig.module.scalaz.arbitrary._
import pureconfig.module.scalaz.equal._
import pureconfig.module.scalaz.instances._
import pureconfig.{ ConfigConvert, ConfigReader, ConfigWriter }
import scalaz.scalacheck.ScalazProperties._
import scalaz.std.anyVal.intInstance

class ScalazLawsSuite extends AnyFunSuite with Checkers {
  import ScalazLawsSuite._

  test("contravariant.laws[ConfigWriter]") {
    check(properties2prop(contravariant.laws[ConfigWriter]))
  }

  test("invariantFunctor.laws[ConfigConvert]") {
    check(properties2prop(invariantFunctor.laws[ConfigConvert]))
  }

  test("monadError.laws[ConfigReader, ConfigReaderFailures]") {
    check(properties2prop(monadError.laws[ConfigReader, ConfigReaderFailures]))
  }

  test("semigroup.laws[ConfigReaderFailures]") {
    check(properties2prop(semigroup.laws[ConfigReaderFailures]))
  }

  test("semigroup.laws[ConfigValue]") {
    check(properties2prop(semigroup.laws[ConfigValue]))
  }
}

object ScalazLawsSuite {
  def properties2prop(ps: Properties): Prop = Prop.all(ps.properties.map(_._2).toSeq: _*)
} 
Example 21
Source File: package.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.scalaz

import com.typesafe.config.{ ConfigValue, ConfigValueFactory }
import org.scalacheck.{ Arbitrary, Cogen, Gen }
import org.scalacheck.Arbitrary.{ arbitrary => arb }
import pureconfig.{ ConfigConvert, ConfigReader, ConfigWriter, Derivation }
import pureconfig.error._

import scala.collection.JavaConverters._
import scalaz.scalacheck.ScalaCheckBinding.GenMonad
import scalaz.syntax.applicative._

package object arbitrary {

  private[this] val MaxConfigDepth = 3
  private[this] val MaxCollectionLength = 3

  private[this] def genAny(depth: Int): Gen[Any] = {
    val genScalar: Gen[Any] =
      Gen.oneOf(
        Gen.oneOf(true, false),
        Gen.choose(Double.MinValue, Double.MaxValue),
        Gen.alphaStr)

    def genList(depth: Int): Gen[List[Any]] =
      Gen.choose(0, MaxCollectionLength).flatMap(n =>
        Gen.listOfN(n, Gen.lzy(genAny(depth - 1))))

    def genMap(depth: Int): Gen[Map[String, Any]] =
      Gen.choose(0, MaxCollectionLength).flatMap(n =>
        Gen.mapOfN(n, for { k <- Gen.alphaStr; v <- Gen.lzy(genAny(depth - 1)) } yield (k, v)))

    if (depth == 0) genScalar
    else Gen.frequency(
      3 -> genScalar,
      1 -> genList(depth).map(_.asJava),
      1 -> genMap(depth).map(_.asJava))
  }

  implicit val arbConfigValue: Arbitrary[ConfigValue] =
    Arbitrary(genAny(MaxConfigDepth).map(ConfigValueFactory.fromAnyRef))

  implicit val cogenConfigValue: Cogen[ConfigValue] =
    Cogen[String].contramap[ConfigValue](_.render)

  private[this] val genFailureReason: Gen[FailureReason] =
    Gen.oneOf(
      ^^(Gen.alphaStr, Gen.alphaStr, Gen.alphaStr)(CannotConvert.apply),
      ^(Gen.posNum[Int], Gen.posNum[Int])(WrongSizeString.apply),
      ^(Gen.posNum[Int], Gen.posNum[Int])(WrongSizeList.apply),
      Gen.alphaStr.map(k => KeyNotFound.apply(k)),
      Gen.alphaStr.map(UnknownKey.apply))

  implicit val arbConfigReaderFailures: Arbitrary[ConfigReaderFailures] =
    Arbitrary {
      for {
        n <- Gen.choose(1, MaxCollectionLength)
        l <- Gen.listOfN(n, genFailureReason).map(_.map(r => ConvertFailure(r, None, "")))
      } yield ConfigReaderFailures(l.head, l.tail: _*)
    }

  implicit val cogenConfigReaderFailures: Cogen[ConfigReaderFailures] =
    Cogen[String].contramap[ConfigReaderFailures](_.toString)

  implicit def arbConfigReader[A: Arbitrary]: Arbitrary[ConfigReader[A]] =
    Arbitrary(arb[ConfigValue => Either[ConfigReaderFailures, A]].map(ConfigReader.fromFunction))

  implicit def arbConfigWriter[A: Cogen]: Arbitrary[ConfigWriter[A]] =
    Arbitrary(arb[A => ConfigValue].map(ConfigWriter.fromFunction))

  implicit def arbConfigConvert[A: Arbitrary: Cogen]: Arbitrary[ConfigConvert[A]] =
    Arbitrary {
      for {
        reader <- arb[ConfigReader[A]]
        writer <- arb[ConfigWriter[A]]
      } yield ConfigConvert.fromReaderAndWriter(Derivation.Successful(reader), Derivation.Successful(writer))
    }
} 
Example 22
Source File: package.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.scalaz

import com.typesafe.config.ConfigValue
import org.scalacheck.{ Arbitrary, Gen }
import pureconfig.{ ConfigConvert, ConfigReader, ConfigWriter }
import pureconfig.module.scalaz.arbitrary._
import pureconfig.module.scalaz.instances._

import scalaz.Equal
import scalaz.std.either._
import scalaz.std.tuple._

package object equal {

  implicit def function1Equal[A, B](implicit arbitraryA: Arbitrary[A], equalB: Equal[B]): Equal[A => B] =
    new Equal[A => B] {
      private val samplesCount: Int = 50

      def equal(f: A => B, g: A => B): Boolean = {
        val samples = Gen.listOfN(samplesCount, arbitraryA.arbitrary).sample match {
          case Some(lst) => lst
          case None => sys.error("Could not generate arbitrary values to compare two functions")
        }

        samples.forall(s => equalB.equal(f(s), g(s)))
      }
    }

  implicit def configReaderEqual[A: Equal]: Equal[ConfigReader[A]] =
    Equal.equalBy[ConfigReader[A], ConfigValue => ConfigReader.Result[A]](_.from)

  implicit def configWriterEqual[A: Arbitrary]: Equal[ConfigWriter[A]] =
    Equal.equalBy[ConfigWriter[A], A => ConfigValue](_.to)

  implicit def configConvertEqual[A: Equal: Arbitrary]: Equal[ConfigConvert[A]] =
    Equal.equalBy[ConfigConvert[A], (ConfigReader[A], ConfigWriter[A])] { cc => (cc, cc) }
} 
Example 23
Source File: package.scala    From pureconfig   with Mozilla Public License 2.0 5 votes vote down vote up
package pureconfig.module.scalaz

import com.typesafe.config.ConfigValue
import pureconfig.{ ConfigConvert, ConfigReader, ConfigWriter }
import pureconfig.error.{ ConfigReaderFailure, ConfigReaderFailures, FailureReason }

import scalaz.{ Contravariant, Equal, InvariantFunctor, MonadError, Semigroup, Show }


package object instances {

  implicit val configReaderInstance: MonadError[ConfigReader, ConfigReaderFailures] =
    new MonadError[ConfigReader, ConfigReaderFailures] {
      def point[A](a: => A): ConfigReader[A] =
        ConfigReader.fromFunction { _ => Right(a) }

      def bind[A, B](fa: ConfigReader[A])(f: A => ConfigReader[B]): ConfigReader[B] =
        fa.flatMap(f)

      def raiseError[A](e: ConfigReaderFailures): ConfigReader[A] =
        ConfigReader.fromFunction { _ => Left(e) }

      def handleError[A](fa: ConfigReader[A])(f: ConfigReaderFailures => ConfigReader[A]): ConfigReader[A] =
        ConfigReader.fromFunction { cv =>
          fa.from(cv) match {
            case Left(failures) => f(failures).from(cv)
            case r @ Right(_) => r
          }
        }
    }

  implicit val configWriterInstance: Contravariant[ConfigWriter] =
    new Contravariant[ConfigWriter] {
      def contramap[A, B](fa: ConfigWriter[A])(f: B => A): ConfigWriter[B] =
        fa.contramap(f)
    }

  implicit val configConvertInstance: InvariantFunctor[ConfigConvert] =
    new InvariantFunctor[ConfigConvert] {
      def xmap[A, B](ma: ConfigConvert[A], f: A => B, g: B => A): ConfigConvert[B] =
        ma.xmap(f, g)
    }

  implicit val configValueEqual: Equal[ConfigValue] = Equal.equalA
  implicit val failureReasonEqual: Equal[FailureReason] = Equal.equalA
  implicit val configReaderFailureEqual: Equal[ConfigReaderFailure] = Equal.equalA
  implicit val configReaderFailuresEqual: Equal[ConfigReaderFailures] = Equal.equalA

  implicit val failureReasonShow: Show[FailureReason] = Show.showFromToString
  implicit val configReaderFailureShow: Show[ConfigReaderFailure] = Show.showFromToString
  implicit val configReaderFailuresShow: Show[ConfigReaderFailures] = Show.showFromToString

  implicit val configReaderFailuresSemigroup: Semigroup[ConfigReaderFailures] =
    Semigroup.instance(_ ++ _)

  implicit val configValueSemigroup: Semigroup[ConfigValue] =
    Semigroup.instance((a, b) => b.withFallback(a))
} 
Example 24
Source File: HoconInputTest.scala    From scala-commons   with MIT License 5 votes vote down vote up
package com.avsystem.commons
package hocon

import java.time.{Duration, Period}

import com.avsystem.commons.serialization.json.JsonStringOutput
import com.avsystem.commons.serialization.{GenCodecRoundtripTest, Input, Output}
import com.typesafe.config.{ConfigFactory, ConfigMemorySize, ConfigValue, ConfigValueFactory, ConfigValueType}

class HoconInputTest extends GenCodecRoundtripTest {
  type Raw = ConfigValue

  def writeToOutput(write: Output => Unit): ConfigValue = {
    val sb = new JStringBuilder
    write(new JsonStringOutput(sb))
    val config = ConfigFactory.parseString(s"""{"f":${sb.toString}}""")
    if (config.getIsNull("f")) ConfigValueFactory.fromAnyRef(null) else config.getValue("f")
  }

  def createInput(raw: ConfigValue): Input =
    new HoconInput(raw)

  def rawInput(any: Any): HoconInput =
    new HoconInput(ConfigValueFactory.fromAnyRef(any))

  test("value type reading") {
    assert(rawInput(null).valueType == ConfigValueType.NULL)
    assert(rawInput("kek").valueType == ConfigValueType.STRING)
    assert(rawInput(42).valueType == ConfigValueType.NUMBER)
    assert(rawInput(true).valueType == ConfigValueType.BOOLEAN)
    assert(rawInput(JMap()).valueType == ConfigValueType.OBJECT)
    assert(rawInput(JList()).valueType == ConfigValueType.LIST)
  }

  test("duration reading") {
    assert(rawInput("34s").readDuration() == Duration.ofSeconds(34))
  }

  test("period reading") {
    assert(rawInput("5m").readPeriod() == Period.ofMonths(5))
  }

  test("temporal amount reading") {
    assert(rawInput("5 minutes").readTemporal() == Duration.ofMinutes(5))
    assert(rawInput("5 months").readTemporal() == Period.ofMonths(5))
  }

  test("size in bytes reading") {
    assert(rawInput("100M").readSizeInBytes() == 100 * 1024 * 1024L)
  }

  test("memory size reading") {
    assert(rawInput("100M").readMemorySize() == ConfigMemorySize.ofBytes(100 * 1024 * 1024L))
  }

  test("number reading") {
    assert(rawInput(42.0).readNumber().doubleValue == 42.0)
  }
} 
Example 25
Source File: ParameterValue.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.models

import com.typesafe.config.{Config, ConfigValue, ConfigValueType}
import com.typesafe.config.impl.ConfigInt
import de.frosner.broccoli.services.{ParameterNotFoundException, ParameterValueParsingException}
import org.apache.commons.lang3.StringEscapeUtils
import play.api.libs.json._

import scala.util.{Failure, Success, Try}

object ParameterValue {

  implicit val parameterValueWrites: Writes[ParameterValue] = new Writes[ParameterValue] {
    override def writes(paramValue: ParameterValue) = paramValue.asJsValue
  }

  def fromConfigValue(paramName: String, parameterType: ParameterType, configValue: ConfigValue): Try[ParameterValue] =
    Try {
      parameterType match {
        case ParameterType.Raw =>
          RawParameterValue(configValue.unwrapped().toString)
        case ParameterType.String =>
          StringParameterValue(configValue.unwrapped.asInstanceOf[String])
        case ParameterType.Integer =>
          val number = configValue.unwrapped().asInstanceOf[Number]
          //noinspection ComparingUnrelatedTypes
          if (number == number.intValue())
            IntParameterValue(number.intValue())
          else
            throw ParameterValueParsingException(paramName, s"${number.toString} is not a valid integer")
        case ParameterType.Decimal =>
          DecimalParameterValue(BigDecimal(configValue.unwrapped().asInstanceOf[Number].toString))
      }
    }

  def fromJsValue(parameterName: String,
                  parameterInfos: Map[String, ParameterInfo],
                  jsValue: JsValue): Try[ParameterValue] =
    Try {
      val parameterInfo =
        parameterInfos.getOrElse(parameterName, throw ParameterNotFoundException(parameterName, parameterInfos.keySet))
      fromJsValue(parameterInfo.`type`, jsValue) match {
        case Success(param) => param
        case Failure(ex) =>
          throw ParameterValueParsingException(parameterName, ex.getMessage)
      }
    }

  def fromJsValue(parameterType: ParameterType, jsValue: JsValue): Try[ParameterValue] =
    Try {
      parameterType match {
        case ParameterType.Raw =>
          RawParameterValue(jsValue.as[String])
        case ParameterType.String =>
          StringParameterValue(jsValue.as[String])
        case ParameterType.Integer =>
          IntParameterValue(jsValue.as[Int])
        case ParameterType.Decimal =>
          DecimalParameterValue(jsValue.as[BigDecimal])
      }
    }
}
sealed trait ParameterValue {

  
  def asJsonString: String
  def asJsValue: JsValue
}

case class IntParameterValue(value: Int) extends ParameterValue {
  override def asJsonString: String = value.toString
  override def asJsValue: JsValue = JsNumber(value)
}
case class DecimalParameterValue(value: BigDecimal) extends ParameterValue {
  override def asJsonString: String = value.toString
  override def asJsValue: JsValue = JsNumber(value)
}
case class StringParameterValue(value: String) extends ParameterValue {
  override def asJsonString: String = StringEscapeUtils.escapeJson(value)
  override def asJsValue: JsValue = JsString(value)
}
case class RawParameterValue(value: String) extends ParameterValue {
  override def asJsonString: String = value
  override def asJsValue: JsValue = JsString(value)
} 
Example 26
Source File: DirectoryTemplateSource.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.templates

import java.nio.file.{FileSystems, Files}

import com.typesafe.config.{ConfigFactory, ConfigValue}
import pureconfig._
import pureconfig.module.enumeratum._
import de.frosner.broccoli.models.{ParameterInfo, Template}
import play.api.libs.json.Json

import scala.collection.JavaConverters._
import scala.io.Source
import scala.util.Try


  def loadTemplates(): Seq[Template] = {
    val rootTemplatesDirectory = FileSystems.getDefault.getPath(directory).toAbsolutePath

    if (!Files.isDirectory(rootTemplatesDirectory)) {
      throw new IllegalStateException(s"Templates directory ${rootTemplatesDirectory} is not a directory")
    }

    log.info(s"Looking for templates in $rootTemplatesDirectory")

    val templateDirectories = Files.list(rootTemplatesDirectory).iterator().asScala.filter(Files.isDirectory(_)).toSeq

    log.info(s"Found ${templateDirectories.length} template directories: ${templateDirectories.mkString(", ")}")

    val templates = templateDirectories.flatMap(templateDirectory => {
      val tryTemplate = Try {
        val templateFileContent = Source.fromFile(templateDirectory.resolve("template.json").toString).mkString
        val templateId = templateDirectory.getFileName.toString
        val templateInfo =
          loadConfigOrThrow[TemplateConfig.TemplateInfo](
            ConfigFactory.parseFile(templateDirectory.resolve("template.conf").toFile))
        loadTemplate(templateId, templateFileContent, templateInfo).get
      }
      tryTemplate.failed.map(throwable => log.error(s"Parsing template '$templateDirectory' failed: $throwable"))
      tryTemplate.toOption
    })
    log.info(s"Successfully parsed ${templates.length} templates: ${templates.map(_.id).mkString(", ")}")
    templates.sortBy(_.id)
  }
} 
Example 27
Source File: TemplateConfig.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.templates

import com.typesafe.config.{ConfigObject, ConfigValue}
import de.frosner.broccoli.models.{ParameterType, ParameterValue}
import pureconfig.ConfigReader
import pureconfig.error.{ConfigReaderFailures, ThrowableFailure}

import scala.collection.JavaConversions._
import scala.util.{Failure, Success, Try}

object TemplateConfig {

  implicit val configReader: ConfigReader[TemplateInfo] = new ConfigReader[TemplateInfo] {
    override def from(configOrig: ConfigValue): Either[ConfigReaderFailures, TemplateInfo] =
      Try {
        val confObj = configOrig.asInstanceOf[ConfigObject]
        val config = confObj.toConfig
        val description = Try(config.getString("description")).toOption
        val parameters = config
          .getObject("parameters")
          .map {
            case (paramName, paramConfig) =>
              val paramValueObj = paramConfig.asInstanceOf[ConfigObject].toConfig
              val maybeName = Try(paramValueObj.getString("name")).toOption
              val maybeSecret = Try(paramValueObj.getBoolean("secret")).toOption
              // Don't wrap the call as we want it to fail in case the wrong type or no type is supplied
              val paramType = ParameterType.withName(paramValueObj.getString("type"))
              val maybeOrderIndex = Try(paramValueObj.getInt("order-index")).toOption
              val maybeDefault = Try(paramValueObj.getValue("default")).toOption.map { paramValueConf =>
                ParameterValue.fromConfigValue(
                  paramName,
                  paramType,
                  paramValueConf
                ) match {
                  case Success(paramDefault) => paramDefault
                  case Failure(ex)           => throw ex
                }
              }
              (paramName, Parameter(maybeName, maybeDefault, maybeSecret, paramType, maybeOrderIndex))
          }
          .toMap
        TemplateInfo(description, parameters)
      } match {
        case Success(e)  => Right(e)
        case Failure(ex) =>
          // TODO: Improve this error throwing.
          Left(ConfigReaderFailures(ThrowableFailure(ex, None, "")))
      }
  }

  final case class TemplateInfo(description: Option[String], parameters: Map[String, Parameter])

  final case class Parameter(name: Option[String],
                             default: Option[ParameterValue],
                             secret: Option[Boolean],
                             `type`: ParameterType,
                             orderIndex: Option[Int])

} 
Example 28
Source File: JsonConfig.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.util

import com.typesafe.config.ConfigValueType.{BOOLEAN, NULL, NUMBER, STRING}
import com.typesafe.config.{ConfigList, ConfigObject, ConfigValue}
import play.api.Configuration
import play.api.libs.json._

import scala.collection.JavaConverters._

object JsonConfig {
  implicit val configValueWrites: Writes[ConfigValue] = Writes(
    (value: ConfigValue) ⇒
      value match {
        case v: ConfigObject             ⇒ configWrites.writes(Configuration(v.toConfig))
        case v: ConfigList               ⇒ JsArray(v.asScala.map(x ⇒ configValueWrites.writes(x)))
        case v if v.valueType == NUMBER  ⇒ JsNumber(BigDecimal(v.unwrapped.asInstanceOf[Number].toString))
        case v if v.valueType == BOOLEAN ⇒ JsBoolean(v.unwrapped.asInstanceOf[Boolean])
        case v if v.valueType == NULL    ⇒ JsNull
        case v if v.valueType == STRING  ⇒ JsString(v.unwrapped.asInstanceOf[String])
      }
  )

  implicit def configWrites = OWrites { (cfg: Configuration) ⇒
    JsObject(cfg.subKeys.map(key ⇒ key → configValueWrites.writes(cfg.underlying.getValue(key))).toSeq)
  }
}