Created
May 5, 2013 14:16
-
-
Save vasily-kirichenko/5520937 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module NonNullListSerialization | |
open System | |
open System.IO | |
open System.Text | |
open Newtonsoft.Json | |
open FSharpx.Collections | |
open System.Collections.Generic | |
open Newtonsoft.Json.Serialization | |
open Newtonsoft.Json.Converters | |
open Microsoft.FSharp.Reflection | |
type NonEmptyListConverter() = | |
inherit JsonConverter() | |
override x.CanConvert(t:Type) = | |
t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<NonEmptyList<_>> | |
override x.WriteJson(writer, value, serializer) = | |
let list = value :?> System.Collections.IEnumerable |> Seq.cast | |
serializer.Serialize(writer, list) | |
override x.ReadJson(reader, t, _, serializer) = | |
let itemType = t.GetGenericArguments().[0] | |
let collectionType = typedefof<IEnumerable<_>>.MakeGenericType(itemType) | |
let collection = serializer.Deserialize(reader, collectionType) :?> System.Collections.IEnumerable |> Seq.cast | |
match collection |> Seq.toList with | |
| [] -> invalidOp "NonEmptyList cannot be empty" | |
| h :: t -> NonEmptyList.create h t :> _ | |
let s = new JsonSerializer() | |
s.Converters.Add(new NonEmptyListConverter()) | |
let serialize o = | |
use ms = new MemoryStream() | |
(use jsonWriter = new JsonTextWriter(new StreamWriter(ms)) | |
s.Serialize(jsonWriter, o)) | |
ms.ToArray() | |
let deserialize (t, data: byte array) = | |
use ms = new MemoryStream(data) | |
use jsonReader = new JsonTextReader(new StreamReader(ms)) | |
s.Deserialize(jsonReader, t) | |
let twoWay o = | |
let bytes = serialize o | |
(o.GetType(), bytes) |> deserialize | |
// OK | |
let l = twoWay <| NonEmptyList.createParamsArray ("a", [|"b"; "c"|]) | |
type Complex = { List: NonEmptyList<string> } | |
// System.ArgumentException: Object of type 'FSharpx.Collections.NonEmptyList`1[System.Object]' cannot be converted to type 'FSharpx.Collections.NonEmptyList`1[System.String]'. | |
let c = twoWay <| { List = NonEmptyList.createParamsArray ("a", [|"b"; "c"|]) } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment