fthomas / fthomas/refined

[pureconfig] Refined keys for Map[String, T]

Open
#443 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scala
Stars
1.7k
Forks
152
Avg merge
1h 20m
Merged PRs (30d)
6

Description

PureConfig provides an instance of `ConfigReader` for maps. (see https://github.com/pureconfig/pureconfig/blob/v0.9.0/core/src/main/scala/pureconfig/DerivedReaders.scala#L198)

Unfortunately, it seems impossible to provide a refinement for the map key without writing a custom `ConfigReader`
I think `refined` should provide a `ConfigReader[Map[Refined[String, ?], T]]` that would allow for map keys to be something like `String Refined MaxSize[W.`249`.T]`.

I attempted to create such a `ConfigReader` but failed to provide a generic definition.

I did, however, manage to make a specific one for my use case (Kafka topics), so maybe that can help:

```scala
// https://github.com/apache/kafka/blob/1.0.0/clients/src/main/java/org/apache/kafka/common/internals/Topic.java
type TopicSpec = NonEmpty And MaxSize[W.`249`.T] And MatchesRegex[W.`"[a-zA-Z0-9\\\\.\\\\-_]+"`.T] And Not[Equal[W.`"."`.T]] And Not[Equal[W.`".."`.T]]
type Topic = String Refined TopicSpec

implicit def deriveTopicMap[T](implicit reader: Derivation[Lazy[ConfigReader[T]]]): ConfigReader[Map[Topic, T]] = new ConfigReader[Map[Topic, T]] {
override def from(cur: ConfigCursor): Either[ConfigReaderFailures, Map[Topic, T]] = {
cur.asMap.right.flatMap { map =>
map.foldLeft[Either[ConfigReaderFailures, Map[Topic, T]]](Right(Map())) {
case (acc, (key, valueConf)) => {
val topic = refineV[TopicSpec](key)
topic.map { key =>
combineResults(acc, reader.value.value.from(valueConf)) { (map, value) => map + (key -> value) }
}.getOrElse(Right(Map.empty[Topic, T]))
}
}
}
}
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.