Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add combinators to control the nesting in Codecs #89

Open
gusty opened this issue Jun 17, 2020 · 1 comment
Open

Add combinators to control the nesting in Codecs #89

gusty opened this issue Jun 17, 2020 · 1 comment

Comments

@gusty
Copy link
Member

gusty commented Jun 17, 2020

See for instance the function proposed here

https://stackoverflow.com/questions/62287765/how-to-serialize-deserialize-this-aws-api-with-f/62291052#62291052

@gusty gusty changed the title Add a combinator that allows inserting json directly, without nesting Add combinators to allows inserting json directly, without nesting and t Jul 20, 2020
@gusty gusty changed the title Add combinators to allows inserting json directly, without nesting and t Add combinators to control the nesting in Codecs Jul 20, 2020
@gusty
Copy link
Member Author

gusty commented Jul 20, 2020

The other combinator we should consider adding is being used already in our tests:

let tag prop codec =
    Codec.ofConcrete codec
    |> Codec.compose (
                        (fun o -> match IReadOnlyDictionary.tryGetValue prop o with Some (JObject a) -> Ok a | _ -> Decode.Fail.propertyNotFound prop o), 
                        (fun x -> if Seq.isEmpty x then zero else Dict.toIReadOnlyDictionary (dict [prop, JObject x]))
                     )
    |> Codec.toConcrete

Here's a sample usage:

type CommandParams =
  | FooParams of arg1: int * arg2: int
  | BarParams of arg1: string
  with
    static member JsonObjCodec =
      jchoice
        [
            fun _ a -> BarParams a
            <!> jreq "method" (function BarParams _ -> Some "bar" | _ -> None)
            <*> tag "params" (
                fun _ a -> a
                <!> jreq "type" (function BarParams _ -> Some "bar.params" | _ -> None)
                <*> jreq "arg1" (function BarParams (arg1 = x) -> Some  x | _ -> None))
            fun _ (a1, a2) -> FooParams (a1, a2)
            <!> jreq "method" (function FooParams _ -> Some "foo" | _ -> None)
            <*> tag "params" (
                fun _ a1 a2 -> (a1, a2)
                <!> jreq "type" (function FooParams _ -> Some "foo.params" | _ -> None)
                <*> jreq "arg1" (function FooParams (arg1 = x) -> Some  x | _ -> None)
                <*> jreq "arg2" (function FooParams (arg2 = x) -> Some  x | _ -> None))
        ]

let jsontext1 = """
{
  "method": "foo",
  "params": {"type": "foo.params", "arg1": 1, "arg2": 2}
}"""

let jsontext2 = """
{
  "method": "bar",
  "params": {"type": "bar.params", "arg1": "beep"}
}
"""

There are simpler use cases in out tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant