以下是袖口,但它應該工作。請注意,我假設你只是想在當值是空分隔兩側空字符串,而我沒有驗證該月值是1到12之間
import argonaut._, Argonaut._
import scalaz._, Scalaz._
case class DateValue(year: Option[Int] = None, month: Option[Int] = None)
object YearMonth {
def unapplySeq(s: String) =
"""((?:\d\d\d\d)?)/((?:\d?\d)?)""".r.unapplySeq(s).map {
case List("", "") => List(None, None)
case List(y, "") => List(Some(y.toInt), None)
case List("", m) => List(None, Some(m.toInt))
case List(y, m) => List(Some(y.toInt), Some(m.toInt))
}
}
implicit val DateValueCodecJson: CodecJson[DateValue] = CodecJson(
{ case DateValue(year, month) => jString(~year + "/" + ~month) },
c => c.as[String].flatMap {
case YearMonth(y, m) => DecodeResult.ok(DateValue(y, m))
case _ => DecodeResult.fail("Not a valid date value!", c.history)
}
)
然後:
val there = Parse.decodeValidation[DateValue](""""2013/12"""")
val back = there.map(DateValueCodecJson.encode)
這給了我們:
scala> println(there)
Success(DateValue(Some(2013),Some(12)))
scala> println(back)
Success("2013/12")
正如預期的那樣。
訣竅是提供您自己的編碼和解碼功能CodecJson.apply
。編碼函數非常簡單 - 它只需要一些編碼類型並返回Json
值。解碼方法稍微複雜一點,因爲它需要一個HCursor
並返回一個DecodeResult
,但這些也很容易處理。
正是我在找的東西。謝謝你,特拉維斯。 '〜'操作符對我來說也是一個很棒的發現。 – Tvaroh