Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with Giraffe #39

Open
codingedgar opened this issue Aug 15, 2020 · 4 comments
Open

Integration with Giraffe #39

codingedgar opened this issue Aug 15, 2020 · 4 comments

Comments

@codingedgar
Copy link

What's the proper way to integrate with Giraffe? (or implement the IJsonSerializer)

https://github.com/giraffe-fsharp/Giraffe/blob/master/DOCUMENTATION.md#serialization

@vsapronov
Copy link
Collaborator

vsapronov commented Aug 15, 2020

Hi @codingedgar . This is a great idea. I quickly took a look at IJsonSerializer I think it should be fairly easy to implement it with API provided by FSharp.Json.
This https://github.com/giraffe-fsharp/Giraffe/blob/8a4300e6e8fc6fac2119da044073ba8e2bf22940/src/Giraffe/Serialization.fs#L73-L115 looks pretty trivial.
I'm not sure if I will be providing library with such implementation myself. I soon will need to take a look at F# with Giraffe and will decide it then.

@danieljsummers
Copy link

I just came here to ask the same thing. I just finished writing it (though I don't have tests for it yet); would this be something you'd be interested in for this project, or should I package it up myself?

BTW, here's my implementation.

  open FSharp.Control.Tasks.V2.ContextInsensitive
  open FSharp.Json
  open Giraffe.Serialization
  open System
  open System.IO
  open System.Text
  open System.Threading.Tasks

  /// A serializer implementation using FSharp.Json's serialization functions
  type FSharpJsonSerializer () =
    interface IJsonSerializer with
      member __.SerializeToString<'T> (x : 'T) =
        Json.serialize x
      member __.SerializeToBytes<'T> (x : 'T) =
        (Json.serialize >> Encoding.UTF8.GetBytes) x
      member this.SerializeToStreamAsync<'T> (x : 'T) (stream : Stream) =
        task {
          do! stream.WriteAsync (ReadOnlyMemory ((this :> IJsonSerializer).SerializeToBytes x))
          } :> Task

      member __.Deserialize<'T> (json : string) =
        Json.deserialize<'T> json
      member this.Deserialize<'T> (bytes : byte array) =
        Encoding.UTF8.GetString bytes |> (this :> IJsonSerializer).Deserialize<'T>
      member this.DeserializeAsync<'T> (stream : Stream) =
        task {
          let! bytes =
            match stream.CanSeek with
            | true ->
                task {
                  let bytes = Array.create (int stream.Length) (byte 0)
                  let! _    = stream.ReadAsync (Memory bytes)
                  return bytes
                }
            | false ->
                task {
                  let mutable recv : byte[] list = []
                  let mutable moreBytes = true
                  let rdr = new BufferedStream(stream)
                  let buf = Array.create 1024 (byte 0)
                  while (moreBytes) do
                    match! rdr.ReadAsync (buf, 0, 1024) with
                    | 0 -> moreBytes <- false
                    | byteCount ->
                        recv      <- (Array.chunkBySize byteCount buf).[0] :: recv
                        moreBytes <- byteCount = 1024
                  return List.foldBack (fun recvBytes allBytes -> Array.concat [ allBytes; recvBytes ]) recv [||]
                  }
          return (this :> IJsonSerializer).Deserialize<'T> bytes
        }

@danieljsummers
Copy link

Just looked at the Giraffe implementation; it looks a bit cleaner than mine. (I'm not sure that I've thrown > 1,024 bytes at it yet.)

@vsapronov
Copy link
Collaborator

@danieljsummers I can package it and publish it as FSharp.Json.Giraffe (I have booked the package name already). I will check code and put it into FSharp.Json.Giraffe soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants