2014-10-22 2 views
2

Я определил пользователь, который имеет "видео" информация:Как использовать аргонавт для анализа необязательного настраиваемого поля?

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

И у нас есть такая JSON:

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

я могу использовать такой код, чтобы разобрать его:

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 
} 

Из DecodeVideo вы можете видеть, что я просто хочу предоставить видео, только если предоставлены оба «заголовка» и «url».

Это хорошо работает, если в json содержится раздел «видео». Но если это не так, аргонавт сообщит, что раздел «видео» не предоставляется.

Как сделать «видео» необязательным?

+0

Какую версию аргонавта вы используете? Я не могу найти этот метод 'как [T]', который вы используете, или любую документацию по этому подходу к десериализации на своем веб-сайте. – Nate

ответ

-1

Я не могу понять, как ваш код интегрируется с аргонавтом. Все экземпляры метода 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 

В частности, обратите внимание, что понимание выхода должно возвращать Option[String], так как ваш выход, вероятно, будет оборачивать результат в DecodeJson так же, как мой пример оборачивает его в List. Обратите внимание, что asInstanceOf по None не является обязательным; IntelliJ жалуется, что его нет, но на самом деле он просто компилируется.

Конкретная вещь, которой я считаю, что вам не хватает, является упаковка Video в Some.

Смежные вопросы