-
-
Notifications
You must be signed in to change notification settings - Fork 42
Open
Description
I think we can make writing JSON programaticaly a little more convenient without touching the core abstractions.
Before:
Encode.object
[
"foo",
Encode.object
[
"bar", Encode.list [ Encode.int 123; Encode.string "abc" ]
]
]After:
json {
"foo" <~
json {
"bar" <~ json {
123
"abc"
}
}
}{
"foo": {
"bar": [
123,
"abc"
]
}
}Happy to riff on the exact syntax.
And the implementation (could not doubt be more efficient):
#r "nuget: Thoth.Json.Core"
open Thoth.Json.Core
type JsonValueHelper =
static member inline ($) (_ : JsonValueHelper, value : IEncodable) =
value
static member inline ($) (_ : JsonValueHelper, value : string) =
Encode.string value
static member inline ($) (_ : JsonValueHelper, value : int) =
Encode.int value
static member inline ($) (_ : JsonValueHelper, value : int64) =
Encode.int64 value
static member inline ($) (_ : JsonValueHelper, value : bool) =
Encode.bool value
// etc...
let inline toJsonValue value : IEncodable =
Unchecked.defaultof<JsonValueHelper> $ value
type JsonProperty = string * IEncodable
type JsonBuilder() =
membe this.Yield(prop : JsonProperty) =
Seq.singleton prop
member inline this.Yield(value : _) =
Seq.singleton (toJsonValue value)
member this.YieldFrom(props : JsonProperty seq) =
props
member this.YieldFrom(xs : IEncodable seq) =
xs
member this.Combine(xs : JsonProperty seq, ys) =
Seq.append xs ys
member this.Combine(xs : IEncodable seq, ys) =
Seq.append xs ys
member this.Zero() =
Seq.empty
member this.Delay(f) =
f ()
member this.For(seq : seq<'a>, mapFunction : 'a -> seq<'b>) =
seq
|> Seq.collect mapFunction
member this.Run(props : JsonProperty seq) : IEncodable =
props
|> Seq.toList
|> Encode.object
member this.Run(value : IEncodable) : IEncodable =
value
member this.Run(elements : IEncodable seq) : IEncodable =
elements
|> Seq.toList
|> Encode.list
let json = JsonBuilder()
let inline (<~) (name : string) (value : _) : JsonProperty =
name, toJsonValue valuegoswinrgoswinr
Metadata
Metadata
Assignees
Labels
No labels