fsprojects / Fleece

Json mapper for F#
http://fsprojects.github.io/Fleece
Apache License 2.0
199 stars 31 forks source link

Operator `<|>` logic looks wrong, why would I need to use both codes for encoding #141

Open xperiandri opened 1 year ago

xperiandri commented 1 year ago

I expect that operator <|> allows to execute the first decoder but if it fails try the alternative one. But for encoding that it always uses a source encoder. While currently it uses both encoders that has no sense to me.

wallymathieu commented 7 months ago

Do you have an example so that we can add a reproduction for this issue @xperiandri ?

xperiandri commented 7 months ago

Imagine I have an old wrong codec stroring

{
  "Wrong": "",
  "right": 5
}

then I write code that stores both properties correctly

{
  "wrong": "",
  "right": 5
}

then I expect my output to be

{
  "wrong": "",
  "right": 5
}

but not

{
  "Wrong": "",
  "wrong": "",
  "right": 5
}

Reading is sequential (try next if failed) But writing is single (the first one codec wins)

wallymathieu commented 7 months ago

So for an example:

#r "nuget: System.Json, 4.7.1"
#r "nuget: FSharpPlus, 1.2.2"
#r "nuget: Fleece.SystemTextJson, 0.10.0"

open Fleece
open Fleece.SystemTextJson

type Rectangle = Rectangle of width  : float* length : float
    with
        static member create w l = Rectangle (w, l)
        static member oldCodec = 
            Rectangle.create
            <!> jreq "Wrong" (function Rectangle (x, _) -> Some x)
            <*> jreq "right" (function Rectangle (_, x) -> Some x)
        static member newCodec =
            Rectangle.create
            <!> jreq "wrong" (function Rectangle (x, _) -> Some x)
            <*> jreq "right" (function Rectangle (_, x) -> Some x)
        static member JsonObjCodec : Codec<PropertyList<Encoding>, Rectangle> =
            Rectangle.newCodec <|> Rectangle.oldCodec

let x = Rectangle (1.0,1.0);;  
toJsonText x;;

this seems a bit like:

let y = 0b011 ||| 0b101
y.ToString("B")