Как видите, Either
отсутствует в списке поддерживаемых типов из коробки .
Однако Either
подпадает под запечатанное семейство , поэтому :
@ ConfigSource.string("""{ type: left, value: "test" }""").load[Either[String, String]]
res15: ConfigReader.Result[Either[String, String]] = Right(Left("test"))
@ ConfigSource.string("""{ type: right, value: "test" }""").load[Either[String, String]]
res16: ConfigReader.Result[Either[String, String]] = Right(Right("test"))
работает. Если у вас запечатанная иерархия, то, что будет делать pureconfig, это потребовать объект, имеющий поле type
- это поле будет использоваться для отправки анализа на указанный подтип c. Все остальные поля будут переданы как поля для анализа в этом подтипе.
Если это не сработает, вы можете попробовать реализовать код c самостоятельно:
// just an example
implicit def eitherReader[A: ConfigReader, B: ConfigReader] =
new ConfigReader[Either[A, B]] {
def from(cur: ConfigCursor) =
// try left, if fail try right
ConfigReader[A].from(cur).map(Left(_)) orElse ConfigReader[B].from(cur).map(Right(_))
}
который теперь не требует значения различения:
@ ConfigSource.string("""{ test: "test" }""").load[Map[String, Either[String, String]]]
res26: ConfigReader.Result[Map[String, Either[String, String]]] = Right(Map("test" -> Left("test")))
Это не предусмотрено по умолчанию, поскольку вам придется ответить на несколько вопросов самостоятельно:
- как вы решите, если Вы должны go с
Left
или Right
декодированием? - делает
Left
отступление Right
или Right
отступление Left
имеет смысл? - как насчет
Either[X, X]
?
Если вы понимаете, что такое ожидаемое поведение, вы можете реализовать свой изношенный код c и использовать его при деривации.