2014-10-22 7 views
2

은 내가 '동영상'정보를 가진 사용자 정의 :argonaut를 사용하여 선택적 사용자 정의 필드를 구문 분석하는 방법은 무엇입니까?

case class User(name:String, video: Option[Video]) 
case class Video(title:String, url:String) 

을 그리고 우리는 이러한 JSON 있습니다

implicit def DecodeUser: DecodeJson[User] = for { 
    name <- as[String]("name") 
    video <- as[Option[Video]]("video") 
} yield User(name, video) 

implicit def DecodeVideo: DecodeJson[Option[Video]] = for { 
    titleOpt <- as[Option[String]]("title") 
    urlOpt <- as[Option[String]]("url") 
} yield (titleOpt, urlOpt) match { 
    case (Some(title), Some(url)) => Video(title, url) 
    case _ => None 
} 
: 나는 그것을 구문 분석과 같은 코드를 사용할 수 있습니다

{ 
    "name": "somename", 
    "video": { 
     "title": "my-video", 
     "url": "https://youtube.com/watch?v=123123" 
    } 
} 

DecodeVideo에서 "title"과 "url"이 모두 제공된 경우에만 비디오를 제공하고 싶다는 것을 알 수 있습니다.

json에 '동영상'섹션이 포함 된 경우 제대로 작동합니다. 그러나 그렇지 않다면, argonaut는 "비디오"섹션이 제공되지 않는다고보고 할 것입니다.

"비디오"를 선택하는 방법은 무엇입니까?

+0

어떤 argonaut 버전을 사용하고 있습니까? 나는 당신이 사용하고있는이'as [T]'메서드 나 그들의 웹 사이트에있는 deserialization에 대한이 접근법에 대한 문서를 찾을 수 없다. – Nate

답변

-1

코드가 argonaut와 어떻게 통합되는지 알 수 없습니다. as[T] 메소드의 모든 인스턴스가 사용중인 서명과 일치하지 않는 것 같습니다.

object Test { 

    case class Video(title: String, url: String) 

    def test(titleOptIn: List[Option[String]], urlOptIn: List[Option[String]]): List[Option[Video]] = { 
    for { 
     titleOpt <- titleOptIn 
     urlOpt <- urlOptIn 
    } yield (titleOpt, urlOpt) match { 
     case (Some(title), Some(url)) => Some(Video(title, url)) 
     case _ => None.asInstanceOf[Option[Video]] 
    } 
    } 

    def main(args: Array[String]): Unit = { 
    test(List(Some("t")), List(Some("u"), None)).foreach(println) 
    } 
} 

// Has Output: 
// Some(Video(t,u)) 
// None 

는 당신의 구체적인 수율 내 예는 List에 랩처럼 DecodeJson에 결과를 포장 될 가능성이 있기 때문에 수율 이해가 Option[String]을 반환해야 함을 유의 : 어쨌든, 여기에 비슷한 문제 및 해결책입니다. 없음의 asInstanceOf은 선택 사항입니다. IntelliJ는 거기에 없다면 불평하지만 실제 컴파일은 잘됩니다.

내가 누락되었다고 생각하는 구체적인 점은 VideoSome에 배치하는 것입니다.