2017-11-29 19 views
1

이것이 스칼라 pureconfig의 본질에 반하는 것입니다. 그러나 ... 이 사례 클래스에 대한 스칼라 pureconfig 구성 판독을 구현하는 것이 실현 가능합니까? Integer, Double, Array [Strings], Array [Integer], Array [Double]과 같은 강력한 형식의 값 (String)을 생성합니다. 예 : 당신은 그 필드 ANY 할 수구성 도중에 scala pureconfig를 할당하십시오.

답변

4

하지 않습니다 Any을 읽는 방법을 제공하십시오. 특정 클래스에 대해 당신이 Any을 읽고 싶은 경우에 당신은 그 클래스의 맥락에서 Any을위한 코덱을 정의 할 수 있습니다 :

case class Filter(field: String, operator: String, variable: Any) 

implicit val readFilter = { 
    implicit val readAny = new ConfigReader[Any] { 
    def from(config: ConfigValue): Either[ConfigReaderFailures, Any] = { 
     Right(config.unwrapped()) 
    } 
    } 
    ConfigReader[Filter] 
} 

을 그리고 당신은 Filter

val config = ConfigFactory.parseString(
    """ 
    { 
     field: "foo" 
     operator: "bar" 
     variable: [] 
    } 
    """) 
println(pureconfig.loadConfig[Filter](config)) 
// will print Right(Filter(foo,bar,[])) 

unwrappedConfigValue 변환 읽을 수 있습니다 재귀 적으로 Any.

그렇다면 대답은 예, 가능하면 Any을 읽는 방법을 pureconfig에 알려주는 것입니다.

Any에 대해 코덱을 제공하지 않는 이유는 Any이 (가) Scala의 모든 클래스의 조상이고 아무 것도 (예 : 데이터베이스 연결) 코덱을 만들 수 없기 때문입니다.

sealed abstract class MySupportedType 
final case class MyInt(value: Int) extends MySupportedType 
final case class MyDouble(value: Double) extends MySupportedType 
final case class MyListOfString(value: List[String]) extends MySupportedType 
final case class MyListOfInt(value: List[Int]) extends MySupportedType 

final case class Filter2(field: String, operator: String, variable: MySupportedType) 

을 한 후 부산물 값 또는 사용자 정의 코덱을 추출하는 기본 방법을 사용 : 당신은 당신이 유형의 제한된 집합을 기대하고 있음을 알게되면, 당신은 나와있는 것과 같은, 당신은 부산물 모든 것을 포장 할 수 있습니다 대신 Any의 부산물을 사용 MySupportedType

val config = ConfigFactory.parseString(
    """ 
    { 
     field: "foo" 
     operator: "bar" 
     variable: { 
     type: mylistofint 
     value: [] 
     } 
    } 
    """) 
    println(pureconfig.loadConfig[Filter2](config)) 
    // will print Right(Filter2(foo,bar,MyListOfInt(List()))) 

뭔가 당신이 무엇을하고 있는지에 이상이있는 경우 variable 컴파일러의 도움 당신을 가지고 할 수있는 가능한 값을 제한한다.

+0

고마워요! 우수하고 깊은 대답! 현상금이 열리기를 기다리는 중 ... –

+0

@YordanGeorgiev, 나는 보너스를 명시 적으로 지정하지 않으면 자동으로 지정되지 않을 수도 있습니다. 왜냐하면 이미 정답을 선택한 후에 보너스를 시작했기 때문입니다. – SergGr

+0

Tnx! 나는 의심했다. –

0

불쌍한 내 이해도 CoProductHint도 작동합니다 사용자 정의 리더에 접근하는
case class Filter(
    field: String, 
    operator: String, 
    variable: String // should support Int , Double , List[String], List[Int] 
) 

... 기본 pureconfig으로

scala> case class Filter(
    | field: String, 
    | operator: String, 
    | variable: Any // should support Int , Double , List[String], List[Int] 
    | ) 
defined class Filter 

scala> Filter("anurag","data",List(12,34)) 
res5: Filter = Filter(anurag,data,List(12, 34)) 

scala> Filter("anurag","data",List(12.12,34.12)) 
res6: Filter = Filter(anurag,data,List(12.12, 34.12)) 

scala> Filter("anurag","data",List("Hello","Hii")) 
res8: Filter = Filter(anurag,data,List(Hello, Hii)) 
+0

컴파일 할 때 pureconfig 파서를 통과하지 않을 것입니다. –