FsPickler icon indicating copy to clipboard operation
FsPickler copied to clipboard

Is it possible to use a custom pickler for `System.Collections.Immutable.ImmutableList` ?

Open marklam opened this issue 1 year ago • 8 comments

Here's what I've tried:

#r "nuget:FsPickler"

open System.IO
open System.Collections.Immutable
open MBrace.FsPickler

let mkPickler<'t> (resolver : IPicklerResolver) =
    let seqPickler = resolver.Resolve<'t seq> ()

    let writer (w : WriteState) (ns : ImmutableList<'t>) =
        seqPickler.Write w "value" (ns :> 't seq)

    let reader (r : ReadState) : ImmutableList<'t> =
        ImmutableList.CreateRange<'t>(seqPickler.Read r "value")

    Pickler.FromPrimitives(reader, writer)

let resolver : IPicklerResolver =
    let registry = CustomPicklerRegistry()
    registry.RegisterFactory mkPickler
    PicklerCache.FromCustomPicklerRegistry registry

let binarySerializer = FsPickler.CreateBinarySerializer(picklerResolver = resolver)

let storeAndCount value =
    use s = new MemoryStream()
    binarySerializer.Serialize (s, value)
    s.ToArray().Length

let items = seq { 1 .. 100 }
let immutableList = ImmutableList.CreateRange items

printfn "Storing items gives %d bytes" (storeAndCount items)
printfn "Storing ImmutableList gives %d bytes" (storeAndCount immutableList)

But the ImmutableList doesn't seem to trigger my serializer:

Storing items gives 213 bytes
MBrace.FsPickler.NonSerializableTypeException: Type 'System.Collections.Immutable.ImmutableList`1[System.Int32]' is not serializable.
   at MBrace.FsPickler.Utils.Exn`1.get_Value() in C:\Users\eitsarpa\devel\mbrace\FsPickler\src\FsPickler\Utils\Utils.fs:line 59
   at MBrace.FsPickler.PicklerCache.MBrace-FsPickler-IPicklerResolver-Resolve[T]() in C:\Users\eitsarpa\devel\mbrace\FsPickler\src\FsPickler\PicklerGeneration\PicklerCache.fs:line 75
   at MBrace.FsPickler.FsPicklerSerializer.Serialize[T](Stream stream, T value, FSharpOption`1 pickler, FSharpOption`1 streamingContext, FSharpOption`1 encoding, FSharpOption`1 leaveOpen) in C:\Users\eitsarpa\devel\mbrace\FsPickler\src\FsPickler\FsPickler\Serializer.fs:line 60
   at FSI_0004.storeAndCount[a](a value) in C:\Users\markl\AppData\Local\Temp\uw5uvhcg..fsx:line 27
   at <StartupCode$FSI_0004>.$FSI_0004.main@() in C:\Users\markl\AppData\Local\Temp\uw5uvhcg..fsx:line 34
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
Stopped due to error

marklam avatar Aug 14 '23 18:08 marklam