Skip to content

Instantly share code, notes, and snippets.

@naramdash
Last active September 4, 2024 01:53
Show Gist options
  • Save naramdash/504e27ba5dc5bf1d978784185ef65c68 to your computer and use it in GitHub Desktop.
Save naramdash/504e27ba5dc5bf1d978784185ef65c68 to your computer and use it in GitHub Desktop.
my lovely msgpack-cs serializer from jsonelement
open System.Text.Json
open MessagePack
open MessagePack.Resolvers
open MessagePack.Formatters
open MessagePack.FSharp
type JsonElementFormatter() as self =
let jsonElementFormatter = (self :> IMessagePackFormatter<JsonElement>)
interface IMessagePackFormatter<obj> with
member this.Serialize(writer, value, options) =
if value <> null && value.GetType() = typeof<JsonElement> then
jsonElementFormatter.Serialize(&writer, value :?> JsonElement, options)
else
MessagePackSerializer.Serialize(&writer, value, options.WithResolver(StandardResolver.Instance))
member this.Deserialize(reader: byref<MessagePackReader>, options: MessagePackSerializerOptions) =
MessagePackSerializer.Deserialize(&reader, options.WithResolver(StandardResolver.Instance))
interface IMessagePackFormatter<JsonElement> with
member this.Serialize(writer, value, options) =
match value.ValueKind with
| JsonValueKind.Array ->
let items = value.EnumerateArray() |> Seq.toList
writer.WriteArrayHeader(items.Length)
for item in items do
jsonElementFormatter.Serialize(&writer, item, options)
| JsonValueKind.Object ->
let properties = value.EnumerateObject() |> Seq.toList
writer.WriteMapHeader(properties.Length)
for property in properties do
writer.Write(property.Name)
jsonElementFormatter.Serialize(&writer, property.Value, options)
| JsonValueKind.String -> writer.Write(value.GetString())
| JsonValueKind.Number -> writer.Write(value.GetDouble())
| JsonValueKind.True -> writer.Write(true)
| JsonValueKind.False -> writer.Write(false)
| JsonValueKind.Null
| JsonValueKind.Undefined -> writer.WriteNil()
| _ -> failwith "Unsupported JsonElement type"
member this.Deserialize(reader, options) = failwith "Not implemented"
type JsonElementResolver private () =
static let formatter = JsonElementFormatter()
static let instance = CompositeResolver.Create formatter
static member Instance = instance
//
//
//
let options =
[| FSharpResolver.Instance
JsonElementResolver.Instance
StandardResolver.Instance |]
|> MessagePack.Resolvers.CompositeResolver.Create
|> MessagePackSerializerOptions.Standard.WithResolver
let rawjson =
"""{
"name": "John",
"age": 31,
"percentage": -0.9028349872331,
"children": null,
"tall": true,
"human": false,
"cars": [
{ "name": "Ford", "models": [ "Fiesta", "Focus", "Mustang", true ] },
{ "name": "BMW", "models": [ 320, "X3", "X5" ] },
{ "name": "Fiat", "models": [ 500 ] }
] }"""
let value = JsonSerializer.Deserialize<obj>(rawjson)
printfn "value %A" value
let msgpackSer = MessagePackSerializer.Serialize(value, options)
printfn "msgpackSer %A" (msgpackSer)
let msgpackDes = MessagePackSerializer.Deserialize<obj>(msgpackSer, options)
printfn "msgpackDes %A" msgpackDes
printfn "msgpackDes getType() %A" (msgpackDes.GetType())
let reRaw = JsonSerializer.Serialize(msgpackDes)
printfn "reRaw %A" reRaw
//
//
//
let testBool = MessagePackSerializer.Serialize(true, options)
printfn "testBool %A" testBool
let testNumber = MessagePackSerializer.Serialize(123, options)
printfn "testNumber %A" testNumber
let testArray = MessagePackSerializer.Serialize([| 1; 2; 3 |], options)
printfn "testArray %A" testArray
let testAnonymous = MessagePackSerializer.Serialize({| a = "b" |}, options)
printfn "testAnonymous %A" testAnonymous
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment