You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+91-51Lines changed: 91 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ The Json library could be [System.Json](http://bit.ly/1axIBoA), [System.Text.Jso
8
8
Its design is strongly influenced by Haskell's [Aeson](http://hackage.haskell.org/package/aeson-0.7.0.0/docs/Data-Aeson.html). Like Aeson, Fleece is designed around two typeclasses (in [FSharpPlus](https://github.com/fsprojects/FSharpPlus) style) ToJson and OfJson.
let john : Person ParseResult = parseJson """{"name": "John", "age": 44, "children": [{"name": "Katy", "age": 5, "children": []}, {"name": "Johnny", "age": 7, "children": []}]}"""
82
+
let john : Person ParseResult = ofJsonText """{"name": "John", "age": 44, "children": [{"name": "Katy", "age": 5, "children": []}, {"name": "Johnny", "age": 7, "children": []}]}"""
81
83
```
82
84
83
85
Though it's much easier to do this in a monadic or applicative way. For example, using [FSharpPlus](https://github.com/fsprojects/FSharpPlus) (which is already a dependency of Fleece):
@@ -95,18 +97,21 @@ type Person with
95
97
96
98
```
97
99
98
-
Or monadically:
100
+
or with applicatives:
99
101
100
102
101
103
```fsharp
104
+
105
+
open FSharpPlus
106
+
102
107
type Person with
103
108
static member OfJson json =
104
109
match json with
105
110
| JObject o ->
106
111
monad {
107
112
let! name = o .@ "name"
108
-
let! age = o .@ "age"
109
-
let! children = o .@ "children"
113
+
and! age = o .@ "age"
114
+
and! children = o .@ "children"
110
115
return {
111
116
Person.Name = name
112
117
Age = age
@@ -133,37 +138,17 @@ type Person = {
133
138
age : int option
134
139
children: Person list }
135
140
with
136
-
static member JsonObjCodec =
141
+
static member get_Codec () =
137
142
fun f l a c -> { name = (f, l); age = a; children = c }
138
-
<!> jreq "firstName" (Some << fun x -> fst x.name)
139
-
<*> jreq "lastName" (Some << fun x -> snd x.name)
140
-
<*> jopt "age" (fun x -> x.age) // Optional fields: use 'jopt'
141
-
<*> jreq "children" (fun x -> Some x.children)
142
-
143
-
144
-
let p = {name = ("John", "Doe"); age = None; children = [{name = ("Johnny", "Doe"); age = Some 21; children = []}]}
145
-
printfn "%s" (string (toJson p))
146
-
147
-
let john = parseJson<Person> """{"children": [{"children": [],"age": 21,"lastName": "Doe","firstName": "Johnny"}],"lastName": "Doe","firstName": "John"}"""
143
+
<!> jreq "firstName" (Some << fun x -> fst x.name)
144
+
<*> jreq "lastName" (Some << fun x -> snd x.name)
145
+
<*> jopt "age" (fun x -> x.age) // Optional fields can use 'jopt'
Circle <!> jreq "radius" (function Circle x -> Some x | _ -> None)
210
+
Prism <!> jreq "prism" (function Prism (x, y, z) -> Some (x, y, z) | _ -> None)
211
+
}
212
+
|> ofObjCodec
213
+
214
+
```
215
+
216
+
193
217
What's happening here is that we're getting a Codec to/from a Json Object (not neccesarily a JsonValue) which Fleece is able to take it and fill the gap by composing it with a codec from JsonObject to/from JsonValue.
194
218
195
219
We can also do that by hand, we can manipulate codecs by using functions in the Codec module. Here's an example:
196
220
197
221
```fsharp
198
222
open System.Text
223
+
open Fleece.SystemTextJson.Operators
224
+
225
+
type Person = {
226
+
name : string * string
227
+
age : int option
228
+
children: Person list }
229
+
with
230
+
static member JsonObjCodec: Codec<PropertyList<Fleece.SystemTextJson.Encoding>, Person> = codec {
231
+
let! f = jreq "firstName" (Some << fun x -> fst x.name)
232
+
and! l = jreq "lastName" (Some << fun x -> snd x.name)
233
+
and! a = jopt "age" (fun x -> x.age) // Optional fields can use 'jopt'
234
+
and! c = jreq "children" (fun x -> Some x.children)
235
+
return { name = (f, l); age = a; children = c } }
199
236
200
237
let personBytesCodec =
201
238
Person.JsonObjCodec
202
239
|> Codec.compose jsonObjToValueCodec // this is the codec that fills the gap to/from JsonValue
203
240
|> Codec.compose jsonValueToTextCodec // this is a codec between JsonValue and JsonText
204
-
|> Codec.invmap Encoding.UTF8.GetString Encoding.UTF8.GetBytes // This is a pair of of isomorphic functions
241
+
|> Codec.invmap (Encoding.UTF8.GetString: byte [] -> string) Encoding.UTF8.GetBytes // This is a pair of of isomorphic functions
242
+
243
+
let p = { name = "John", "Smith"; age = Some 42; children = [] }
0 commit comments