purescript-codec-argonaut icon indicating copy to clipboard operation
purescript-codec-argonaut copied to clipboard

codec for converting String to Json

Open cdepillabout opened this issue 4 years ago • 6 comments

It would be nice if this library provided a codec for converting a String of JSON to an actual Json value.

I imagine it would look like this:

jsonStringCodec :: BasicCodec (Either String) String Json
jsonStringCodec = basicCodec jsonParser stringify

jsonParser and stringify are from purescript-argonaut-core.

I could send a PR adding this if something like this would be accepted.

I'd also appreciate any bikeshedding on the name.


It would also be nice if there was an easy way to combine the above codec with a JsonCodec provided by this library.

Here is a function for composing these, but this is too specific and should be generalized:

composeStringJsonCodec :: forall a. BasicCodec (Either String) String Json -> JsonCodec a -> BasicCodec (Either (Either String JsonDecodeError)) String a
composeStringJsonCodec strJson jsonCodec =
  let hoistedStrJson = hoistCodec (lmap Left) strJson :: BasicCodec (Either (Either String JsonDecodeError)) String Json
      hoistedJsonCodec = hoistCodec (lmap Right) jsonCodec :: BasicCodec (Either (Either String JsonDecodeError)) Json a
  in composeCodec hoistedJsonCodec hoistedStrJson

cdepillabout avatar Nov 08 '19 01:11 cdepillabout

Isn't this what string is for?

JordanMartinez avatar Nov 08 '19 01:11 JordanMartinez

@JordanMartinez So string is for pulling a JSON string out of a Json blob.

jsonStringCodec as I'm suggesting above is from going from a raw JSON blob in a PureScript String to an actual Json value.

cdepillabout avatar Nov 08 '19 03:11 cdepillabout

I wonder if it'd be better to extend JsonDecodeError with a parse error possibility too, so the composition could be more natural. A few times I've done a codec like this and then just dumped the parse error as something like TypeMismatch "JSON".

I guess the downside of adding a new error type is when you know it's impossible, when the codec is just dealing with Json rather than String.

garyb avatar Nov 10 '19 13:11 garyb

@garyb I agree exactly with what you're saying.

It would be easy to extend JsonDecodeError to allow for decoding from String, but the downside is that there are times when you know it is impossible.

I'd be willing to implement it either way. Which do you think is best? You want me to go ahead and just return something like TypeMismatch "JSON" in the error case?

jsonStringCodec :: BasicCodec (Either JsonDecodeError) String Json
jsonStringCodec = ...

cdepillabout avatar Nov 10 '19 23:11 cdepillabout

Another option might be to make JsonDecodeError polymorphic, adding a constructor case that can be used to extend the allowable errors - there are times I've wanted other things that don't fit into the current set too.

Putting Void in there would rule out any other errors then, but allow for parse errors or whatever too.

garyb avatar Nov 10 '19 23:11 garyb

I dunno, yeah, maybe the suggested Either String JsonDecodeError is the simplest way :smile:.

garyb avatar Nov 10 '19 23:11 garyb