0

I'm building an application using the SAFE Stack and I have a System.Uri in my model. When I run my code I get an error in the console "Cannot generate autoencoder for System.Uri..."
My googling has got me to here so far

module CustomEncoders

open Thoth.Json
let uriEncoder (uri:System.Uri) = Encode.string (uri.ToString())

let uriDecoder = ????

let myExtraCoders =
    Extra.empty
    |> Extra.withCustom uriEncoder uriDecoder 


let modelEncoder = Encode.Auto.generateEncoder(extra = myExtraCoders)
let modelDecoder = Decode.Auto.generateDecoder(extra = myExtraCoders)

Then in my App.fs I add

|> Program.withDebuggerCoders CustomEncoders.modelEncoder CustomEncoders.modelDecoder

I think I have understood how to create an encoder but I have no idea how to write the decoder part.
I could obviously replace my System.Uri fields with string but that doesn't feel like the right solution.

David Hayes
  • 7,402
  • 14
  • 50
  • 62

1 Answers1

1

Looking at the Decoder Type, It has the following signature string -> JsonValue -> Result<'T, DecoderError>

Where

  • string: json path to select from the json value
  • JsonValue: raw json to decode

And it either returns an Ok<'T> or Error<DecoderError>

So your uri Decoder will be as follows

let uriDecoder path (token: JsonValue) =
    let value = token.Value<string>()
    match System.Uri.TryCreate(value, System.UriKind.Absolute) with
    | (true, uri) -> Ok uri
    | (false, _) -> Error (path, BadPrimitive("Uri", token))
David Hayes
  • 7,402
  • 14
  • 50
  • 62
Ody
  • 2,012
  • 4
  • 25
  • 35
  • Thanks, I seem to be missing something? I get an error saying Value isn't a member of Object (looking at the source for Thoth.Json this makes sense since JsonValue appears to be an alias for obj? Am I missing a module open? – David Hayes May 29 '22 at 00:32
  • Replacing it with let value = token.ToString() works but I'd love to understand what the issue I was having with the code you proposed is (I'm very much an F# newbie) – David Hayes May 29 '22 at 00:39
  • Ah, I see, I was using `Thoth.Json.Net` which is the .NET native, yeah, using `token.ToString()` is probably the best way to go for you – Ody Jun 12 '22 at 21:59
  • 1
    Ahhh, I'm using it on the client side so I think I have to use Thoth.Json (if I'm understanding that right) – David Hayes Jun 14 '22 at 00:04
  • @DavidHayes Yes, that's correct. They have the same API but have completely different implementations – Ody Jun 18 '22 at 10:51