Skip to content

Commit 2dce0b4

Browse files
committed
Add IsomorphismUnionEncoder
1 parent b77261f commit 2dce0b4

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/FsCodec.NewtonsoftJson/UnionConverter.fs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module private Union =
3131

3232
let getUnion = memoize createUnion
3333

34-
/// Paralells F# behavior wrt how it generates a DU's underlying .NET Type
34+
/// Parallels F# behavior wrt how it generates a DU's underlying .NET Type
3535
let inline isInlinedIntoUnionItem (t : Type) =
3636
t = typeof<string>
3737
|| t.IsValueType

tests/FsCodec.NewtonsoftJson.Tests/UnionConverterTests.fs

+36
Original file line numberDiff line numberDiff line change
@@ -450,3 +450,39 @@ module Nested =
450450
let ser = Serdes.Serialize v
451451
"""{"case":"C","Item":{"case2":"S"}}""" =! ser
452452
test <@ v = Serdes.Deserialize ser @>
453+
454+
/// And for everything else, JsonIsomorphism allows plenty ways of customizing the encoding and/or decoding
455+
module IsomorphismUnionEncoder =
456+
457+
type [<JsonConverter(typeof<TopConverter>)>]
458+
Top =
459+
| S
460+
| N of Nested
461+
and Nested =
462+
| A
463+
| B of int
464+
and TopConverter() =
465+
inherit JsonIsomorphism<Top, Flat<int>>()
466+
override __.Pickle value =
467+
match value with
468+
| S -> { disc = TS; v = None }
469+
| N A -> { disc = TA; v = None }
470+
| N (B v) -> { disc = TB; v = Some v }
471+
override __.UnPickle flat =
472+
match flat with
473+
| { disc = TS } -> S
474+
| { disc = TA } -> N A
475+
| { disc = TB; v = v} -> N (B (Option.get v))
476+
and Flat<'T> = { disc : JiType; v : 'T option }
477+
and [<JsonConverter(typeof<TypeSafeEnumConverter>)>]
478+
JiType = TS | TA | TB
479+
480+
let [<Fact>] ``Can control the encoding to the nth degree`` () =
481+
let v : Top = N (B 42)
482+
let ser = Serdes.Serialize v
483+
"""{"disc":"TB","v":42}""" =! ser
484+
test <@ v = Serdes.Deserialize ser @>
485+
486+
let [<FsCheck.Xunit.Property>] ``can roundtrip`` (value : Top) =
487+
let ser = Serdes.Serialize value
488+
test <@ value = Serdes.Deserialize ser @>

0 commit comments

Comments
 (0)