Как использовать argonaut для разбора необязательного настраиваемого поля?

Я определил пользователя, у которого есть информация о видео:

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

Это хорошо работает, если JSON содержит раздел "видео". Но если этого не произойдет, аргонавт сообщит, что раздел "видео" не предусмотрен.

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

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,

Другие вопросы по тегам