Skip to content

Commit

Permalink
ReaderUtil: refactor, expose custom value parsing
Browse files Browse the repository at this point in the history
Also, apply it to `BinPack` presets.
  • Loading branch information
kitbellew committed Jun 8, 2024
1 parent 45dc931 commit 4a8326d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ object BinPack {

val never = BinPack.ctor(Site.Never, ParentCtors.Never)
val always = BinPack.ctor(Site.Always, ParentCtors.Always)
val oneline = BinPack.ctor(Site.Oneline, ParentCtors.Oneline)
private val oneline = BinPack.ctor(Site.Oneline, ParentCtors.Oneline)

private val customPresets = ReaderUtil.Custom(never, always, oneline)

implicit val decoder: ConfDecoderEx[BinPack] = Presets
.mapDecoder(generic.deriveDecoderEx(never).noTypos, "binPack") {
case Conf.Bool(true) => always
case Conf.Bool(false) => never
case Conf.Str(str) if str.equalsIgnoreCase("never") => never
case Conf.Str(str) if str.equalsIgnoreCase("always") => always
case Conf.Str(str) if str.equalsIgnoreCase("oneline") => oneline
case Conf.Str(customPresets(obj)) => obj
}

sealed abstract class ParentCtors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import metaconfig._

object ReaderUtil {

private def lowerCaseNoBackticks(s: String): String = s.toLowerCase()
private[config] def lowerCaseNoBackticks(s: String): String = s.toLowerCase()
.replace("`", "")

// Poor mans coproduct reader
Expand All @@ -22,13 +22,21 @@ object ReaderUtil {
oneOfCustomEx(options: _*) { case (_, extract(res)) => res }
}

class Custom[T] private (val m: Map[String, T]) extends AnyVal {
def unapply(tag: String): Option[T] = m.get(lowerCaseNoBackticks(tag))
}
object Custom {
def apply[T: ClassTag](opts: sourcecode.Text[T]*): Custom[T] =
new Custom(opts.map(x => lowerCaseNoBackticks(x.source) -> x.value).toMap)
}

def oneOfCustomEx[T: ClassTag](
options: sourcecode.Text[T]*,
)(f: PartialFunction[(Option[T], Conf), Configured[T]]): ConfCodecEx[T] = {
val m = options.map(x => lowerCaseNoBackticks(x.source) -> x.value).toMap
val custom = Custom(options: _*)
val decoder = ConfDecoderEx.fromPartial[T]("String")(f.orElse {
case (_, Conf.Str(x)) => Configured.opt(m.get(lowerCaseNoBackticks(x))) {
val available = m.keys.mkString(", ")
case (_, Conf.Str(x)) => Configured.opt(custom.unapply(x)) {
val available = custom.m.keys.mkString(", ")
val msg = s"Unknown input '$x'. Expected one of: $available"
ConfError.message(msg)
}
Expand Down

0 comments on commit 4a8326d

Please sign in to comment.