Suggestion: Expose isomorphic functions for parsing a JsonValue from a string
njlr opened this issue · comments
Sometimes, a service should expect valid JSON but does not care about the JSON schema. In these cases, we need to work with JsonValue
but not strongly-typed decoders.
The ability to parse any JSON is already in the library, but (as far as I can tell?) it's not exposed to the user.
Perhaps we could add it to the API?
For .NET:
let tryParseJsonValue (x : string) : Result<JsonValue, string> =
try
use reader = new JsonTextReader(new StringReader(x), DateParseHandling = DateParseHandling.None)
let json = Newtonsoft.Json.Linq.JValue.ReadFrom reader
Ok json
with
| :? Newtonsoft.Json.JsonReaderException as ex ->
Error ("Given an invalid JSON: " + ex.Message)
For Fable:
let tryParseJsonValue (x : string) : Result<JsonValue, string> =
try
let json = JS.JSON.parse x
Ok json
with
| ex when Helpers.isSyntaxError ex ->
Error ("Given an invalid JSON: " + ex.Message)
Then we can inject schema-less JSON into encoders quite naturally:
#r "nuget: Thoth.Json.Net"
open System
open Thoth.Json.Net
let innerJson =
tryParseJsonValue "{ x: 1 }"
|>
function
| Ok x -> x
| Error e -> failwith e
let json =
Encode.object
[
"id", Encode.guid (Guid.NewGuid())
"inner", innerJson
]
let s = Encode.toString 2 json
printfn "%A" s
(*
"{
"id": "bf941f23-db24-4f7d-b5a0-accf8393cd11",
"inner": {
"x": 1
}
}"
*)
You can already do that with the existing API:
Indeed there is the decoder Decode.value
which always succeed:
Line 538 in 78ea91a
let json =
"""{ "x": 1 }"""
let innerJson =
Decode.fromString Decode.value json
|> function
| Ok jsonValue ->
jsonValue
| Error errorMessage ->
failwith errorMessage
let newJson =
Encode.object
[
"id", Encode.guid (System.Guid.NewGuid())
"inner", innerJson
]
let s = Encode.toString 2 newJson
printfn "%A" s
Ah! I hadn't spotted that. Thanks
Ahah no problem :)
TBH it tooks me 20min of writing another answer to think: Hey but don't I have a "discard" decoder already? 🤣