Decoding to types with private constructors.

76 views
Skip to first unread message

Kris Nuttycombe

unread,
Jun 28, 2014, 5:20:50 PM6/28/14
to argona...@googlegroups.com
Suppose that I have a newtype wrapper like the following:

final class StartsWithFoo private (s: String) extends AnyVal.

I want to ensure that no StartsWithFoo instance can be constructed unless the first three characters are 'f', 'o', 'o'

object StartsWithFoo {
  import scalaz.syntax.std.boolean._

  def apply(s: String): Option[StartsWithFoo] = s.startsWith("foo").option(new StartsWithFoo(s))
}

How do I go about producing a DecodeJson[StartsWithFoo]? I am not able to find any mechanism by which I can filter (perhaps reporting an error, and hopefully taking advantage of my validating constructor) a DecodeJson[String] to do so. Validating based upon the state of the HCursor seems ridiculously clunky, and writing a DecodeJson[Option[StartsWithFoo]] strikes me as being stupidly awkward (and inimical to inclusion in a CodecJson; I don't ever want to serialize None) though it's what I'll do if necessary.

Thanks,

Kris

Mark Hibberd

unread,
Jun 28, 2014, 5:36:08 PM6/28/14
to argona...@googlegroups.com

Hey, I am on my phone right now so I will send you a gist later, but you just want something like `implicitly[DecodeJson[String]].flatMap(s => StartsWithFoo(s).cata(DecodeResult.ok, DecodeResult.fail("Didn't start with foo."))`

There should probably be an easier way, but the above is probably the most workable at the moment.

Cheers
Mark

--
You received this message because you are subscribed to the Google Groups "argonaut-json" group.
To unsubscribe from this group and stop receiving emails from it, send an email to argonaut-jso...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mark Hibberd

unread,
Jun 28, 2014, 5:49:29 PM6/28/14
to Kris Nuttycombe, argona...@googlegroups.com

Actually it is provably even easier if you avoid the indirection, see https://github.com/argonaut-io/argonaut/blob/master/src/main/scala/argonaut/DecodeJson.scala#L205 this means you are messing around with the hcusor but it is really just a .string.flatMap(StartsWithFoo) so hopefully not too bad.

On 29/06/2014 7:23 am, "Kris Nuttycombe" <kris.nu...@gmail.com> wrote:
--

Kris Nuttycombe

unread,
Jun 28, 2014, 8:55:09 PM6/28/14
to Mark Hibberd, argona...@googlegroups.com
Thanks! I expected it'd be something trivially simple I was missing. 
Reply all
Reply to author
Forward
0 new messages