README.md 7.75 KB
Newer Older
Dreki Þórgísl's avatar
Dreki Þórgísl committed
1 2
# ljson

3 4 5 6 7
[![Build Status][travis badge]][travis]
[![LFE Versions][lfe badge]][lfe]
[![Erlang Versions][erlang badge]][versions]
[![Tags][github tags badge]][github tags]
[![Downloads][hex downloads]][hex package]
Duncan McGreggor's avatar
Duncan McGreggor committed
8

9 10 11
*An LFE library which provides a unified JSON experience*

[![Project Logo][logo]][logo-large]
Duncan McGreggor's avatar
Duncan McGreggor committed
12

Dreki Þórgísl's avatar
Dreki Þórgísl committed
13

Duncan McGreggor's avatar
Duncan McGreggor committed
14 15 16 17 18 19 20
#### Contents

* [Introduction](#introduction-)
* [Dependencies](#dependencies-)
* [Installation](#installation-)
* [Usage](#usage-)
* [Future](#future-)
21
* [License](#license-)
Duncan McGreggor's avatar
Duncan McGreggor committed
22 23 24


## Introduction [↟](#contents)
Dreki Þórgísl's avatar
Dreki Þórgísl committed
25

Dreki Þórgísl's avatar
Dreki Þórgísl committed
26 27 28
This library was educated by
[Chiron](http://en.wikipedia.org/wiki/Chiron#Students)
to avenge the crimes against JSON and its heirs in the Erlang world. It is
29
destined to search for the
Dreki Þórgísl's avatar
Dreki Þórgísl committed
30 31 32
[Golden Macro](http://en.wikipedia.org/wiki/Golden_Fleece), as
revealed by the
[Cloud Goddess](http://en.wikipedia.org/wiki/Nephele).
Dreki Þórgísl's avatar
Dreki Þórgísl committed
33 34


Duncan McGreggor's avatar
Duncan McGreggor committed
35 36 37
## Dependencies [↟](#contents)

As of version 0.4.0, this project assumes that you have
38
[rebar3](https://github.com/rebar/rebar3) installed somwhere in your `$PATH`.
Duncan McGreggor's avatar
Duncan McGreggor committed
39 40 41 42 43
It no longer uses the old version of rebar. If you do not wish to use rebar3,
you may use the most recent rebar2-compatible release of ljson: 0.3.1.


## Installation [↟](#contents)
Dreki Þórgísl's avatar
Dreki Þórgísl committed
44

45
Just add it to your `rebar.config` deps:
Dreki Þórgísl's avatar
Dreki Þórgísl committed
46 47

```erlang
48 49 50 51
{deps, [
  ...
  {ljson, {git, "git@github.com:lfex/ljson.git", "master"}}
    ]}.
Dreki Þórgísl's avatar
Dreki Þórgísl committed
52 53 54 55 56
```

And then do the usual:

```bash
57
$ make compile
Dreki Þórgísl's avatar
Dreki Þórgísl committed
58 59 60
```


Duncan McGreggor's avatar
Duncan McGreggor committed
61
## Usage [↟](#contents)
Dreki Þórgísl's avatar
Dreki Þórgísl committed
62

Dreki Þórgísl's avatar
Dreki Þórgísl committed
63
The following usage examples are all done from the LFE REPL:
Dreki Þórgísl's avatar
Dreki Þórgísl committed
64 65 66 67 68 69 70 71 72 73

```
$ make repl-no-deps
Starting an LFE REPL ...
Erlang/OTP 17 [erts-6.2] [source] [64-bit] [smp:4:4] [async-threads:10] ...

LFE Shell V6.2 (abort with ^G)
>
```

74

Dreki Þórgísl's avatar
Dreki Þórgísl committed
75
Encode simple LFE data to JSON:
Dreki Þórgísl's avatar
Dreki Þórgísl committed
76 77

```cl
78 79
> (ljson:encode 'a)
#"\"a\""
Dreki Þórgísl's avatar
Dreki Þórgísl committed
80
ok
81 82
> (ljson:encode "a")
#"[97]"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
83
ok
84 85
> (ljson:encode 1)
#"1"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
86
ok
87 88
> (ljson:encode 3.14)
#"3.14"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
89
ok
90 91
> (ljson:encode '(a b c 42))
#"[\"a\",\"b\",\"c\",42]"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
92
ok
93 94
> (ljson:encode #(a b))
#"{\"a\":\"b\"}"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
95
ok
96 97
> (ljson:encode '(#(a b) #(c d)))
#"{\"a\":\"b\",\"c\":\"d\"}"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
98
ok
Dreki Þórgísl's avatar
Dreki Þórgísl committed
99 100 101
>
```

102

Dreki Þórgísl's avatar
Dreki Þórgísl committed
103 104 105
Decode simple JSON:

```cl
106 107
> (ljson:decode #b("\"a\""))
#"a"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
108
ok
109 110
> (ljson:decode "\"a\""))
#"a"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
111
ok
112
> (ljson:decode #b("[97]"))
Dreki Þórgísl's avatar
Dreki Þórgísl committed
113 114
"a"
ok
115
> (ljson:decode #b("1"))
Dreki Þórgísl's avatar
Dreki Þórgísl committed
116 117
1
ok
118
> (ljson:decode #b("3.14"))
Dreki Þórgísl's avatar
Dreki Þórgísl committed
119 120
3.14
ok
121 122
> (ljson:decode #b("[\"a\",\"b\",\"c\",42]"))
(#"a" #"b" #"c" 42)
Dreki Þórgísl's avatar
Dreki Þórgísl committed
123
ok
124 125
> (ljson:decode "{\"a\": \"b\"}")
#(#"a" #"b")
Dreki Þórgísl's avatar
Dreki Þórgísl committed
126
ok
127 128
> (ljson:decode "{\"a\":\"b\",\"c\":\"d\"}")
(#(#"a" #"b") #(#"c" #"d"))
Dreki Þórgísl's avatar
Dreki Þórgísl committed
129
ok
130 131 132
> (ljson:decode
    #B(123 34 97 34 58 34 98 34 44 34 99 34 58 34 100 34 125))
(#(#"a" #"b") #(#"c" #"d"))
Dreki Þórgísl's avatar
Dreki Þórgísl committed
133
ok
Dreki Þórgísl's avatar
Dreki Þórgísl committed
134 135
```

Dreki Þórgísl's avatar
Dreki Þórgísl committed
136 137 138 139 140 141
Decode a JSON data structure (note that, for formatting purposes, the data
below has been presented separated with newlines; this won't work in the
LFE REPL -- you'll need to put it all on one line):

```cl
> (set json-data "{
142 143
  \"First Name\": \"Jón\",
  \"Last Name\": \"Þórson\",
Dreki Þórgísl's avatar
Dreki Þórgísl committed
144 145 146 147
  \"Is Alive?\": true,
  \"Age\": 25,
  \"Height_cm\": 167.6,
  \"Address\": {
148 149
    \"Street Address\": \"í Gongini 5 Postsmoga 108\",
    \"City\": \"Tórshavn\",
150 151
    \"Country\": \"Faroe Islands\",
    \"Postal Code\": \"100\"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
152 153 154 155
  },
  \"Phone Numbers\": [
    {
      \"Type\": \"home\",
156
      \"Number\": \"20 60 30\"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
157 158 159
    },
    {
      \"Type\": \"office\",
160
      \"Number\": \"+298 20 60 20\"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
161 162 163 164 165
    }
  ],
  \"Children\": [],
  \"Spouse\": null}")
> (set data (ljson:decode json-data))
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
(#(#"First Name" #"Jón")
 #(#"Last Name" #"Þórson")
 #(#"Is Alive?" true)
 #(#"Age" 25)
 #(#"Height_cm" 167.6)
 #(#"Address"
   (#(#"Street Address" #"í Gongini 5 Postsmoga 108")
    #(#"City" #"Tórshavn")
    #(#"Country" #"Faroe Islands")
    #(#"Postal Code" #"100")))
 #(#"Phone Numbers"
   ((#(#"Type" #"home") #(#"Number" #"20 60 30"))
    (#(#"Type" #"office") #(#"Number" #"+298 20 60 20"))))
 #(#"Children" ())
 #(#"Spouse" null))
Dreki Þórgísl's avatar
Dreki Þórgísl committed
181 182
```

Dreki Þórgísl's avatar
Dreki Þórgísl committed
183
Now let's take it full circle by encoding it again:
Dreki Þórgísl's avatar
Dreki Þórgísl committed
184 185

```cl
Dreki Þórgísl's avatar
Dreki Þórgísl committed
186 187
> (ljson:prettify (ljson:encode data))
{
188 189
  "First Name": "Jón",
  "Last Name": "Þórson",
Dreki Þórgísl's avatar
Dreki Þórgísl committed
190 191 192 193
  "Is Alive?": true,
  "Age": 25,
  "Height_cm": 167.6,
  "Address": {
194 195 196 197
    "Street Address": "í Gongini 5 Postsmoga 108",
    "City": "Tórshavn",
    "Country": "Faroe Islands",
    "Postal Code": "100"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
198 199 200 201
  },
  "Phone Numbers": [
    {
      "Type": "home",
202
      "Number": "20 60 30"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
203 204 205
    },
    {
      "Type": "office",
206
      "Number": "+298 20 60 20"
Dreki Þórgísl's avatar
Dreki Þórgísl committed
207 208 209 210 211
    }
  ],
  "Children": [],
  "Spouse": null
}
Dreki Þórgísl's avatar
Dreki Þórgísl committed
212 213 214
ok
```

215
Let's do the same, but this time from LFE data:
Dreki Þórgísl's avatar
Dreki Þórgísl committed
216 217

```cl
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
> (set lfe-data
   `(#(#b("First Name") ,(binary ("Jón" utf8)))
     #(#b("Last Name") ,(binary ("Þórson" utf8)))
     #(#b("Is Alive?") true)
     #(#b("Age") 25)
     #(#b("Height_cm") 167.6)
     #(#b("Address")
      #((#(#b("Street Address") ,(binary ("í Gongini 5 Postsmoga 108" utf8)))
        #(#b("City") ,(binary ("Tórshavn" utf8)))
        #(#b("Country") #b("Faroe Islands"))
        #(#b("Postal Code") #b("100")))))
     #(#b("Phone Numbers")
      (#((#(#b("Type") #b("home")) #(#b("Number") #b("20 60 30"))))
       #((#(#b("Type") #b("office")) #(#b("Number") #b("+298 20 60 20"))))))
     #(#b("Children") ())
     #(#b("Spouse") null)))
(#(#B(...)))
> (ljson:prettify (ljson:encode lfe-data))
{
  "First Name": "Jón",
  "Last Name": "Þórson",
  "Is Alive?": true,
  "Age": 25,
  "Height_cm": 167.6,
  "Address": {
    "Street Address": "í Gongini 5 Postsmoga 108",
    "City": "Tórshavn",
    "Country": "Faroe Islands",
    "Postal Code": "100"
  },
  "Phone Numbers": [
    {
      "Type": "home",
      "Number": "20 60 30"
    },
    {
      "Type": "office",
      "Number": "+298 20 60 20"
    }
  ],
  "Children": [],
  "Spouse": null
}
ok
Dreki Þórgísl's avatar
Dreki Þórgísl committed
262 263
```

264 265 266

Extract elements from the original converted data structure as well as
our LFE data structure we just entered directly, above:
Dreki Þórgísl's avatar
Dreki Þórgísl committed
267 268

```cl
269
> (ljson:get data '("First Name"))
270
#"Jón"
271
> (ljson:get data '("Address" "City"))
272
#"Tórshavn"
273
> (ljson:get data '("Phone Numbers" 1 "Type"))
274
#"home"
275
> (ljson:get lfe-data '("First Name") )
276
#"Jón"
277
> (ljson:get lfe-data '("Address" "City")data)
278
#"Tórshavn"
279
> (ljson:get lfe-data '("Phone Numbers" 1 "Type"))
280
#"home"
281 282
```

283
You may also use atom or binary keys:
284

285
```cl
286
> (ljson:get lfe-data '(|Phone Numbers| 1 Number))
287
#"20 60 30"
288
> (ljson:get lfe-data '(#"Phone Numbers" 1 #"Number"))
289
#"20 60 30"
290 291 292
```

Extract elements directly from JSON:
Dreki Þórgísl's avatar
Dreki Þórgísl committed
293

294
```cl
295
> (ljson:get json-data '("First Name") #(json))
296
#"\"J\\u00f3n\""
297
> (ljson:get json-data '("Address" "City") #(json))
298
#"\"T\\u00f3rshavn\""
299
> (ljson:get json-data '("Phone Numbers" 1 "Type") #(json))
300
#"\"home\""
Dreki Þórgísl's avatar
Dreki Þórgísl committed
301 302
```

303

Duncan McGreggor's avatar
Duncan McGreggor committed
304
## Under the Deck [↟](#contents)
Dreki Þórgísl's avatar
Dreki Þórgísl committed
305 306 307

The Argonauts that are rowing this thing consist of the following:

308
* mochijson2 - for encoding of nested data
309 310
* jsx - for decoding, `prettify` and `minify`
* dict - (wrapped as `pairs`) for large key/value lists
Dreki Þórgísl's avatar
Dreki Þórgísl committed
311 312 313
* proplists/lists of tuples - for small key/value lists


314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
## License [↟](#contents)

Apache Version 2 License

Copyright © 2014-2015, Dreki Þórgísl

Copyright © 2015, arpunk

Copyright © 2015-2016, Duncan McGreggor <oubiwann@gmail.com>


<!-- Named page links below: /-->

[logo]: priv/images/jason-argonauts-small.png
[logo-large]: http://dropr.com/coenhamelink/15218/jason_and_the_argonauts/+?p=97582
[org]: https://github.com/lfex
[github]: https://github.com/lfex/ljson
[gitlab]: https://gitlab.com/lfex/ljson
[travis]: https://travis-ci.org/lfex/ljson
[travis badge]: https://img.shields.io/travis/lfex/ljson.svg
[lfe]: https://github.com/rvirding/lfe
[lfe badge]: https://img.shields.io/badge/lfe-1.2.0-blue.svg
[erlang badge]: https://img.shields.io/badge/erlang-R15%20to%2019.1-blue.svg
[versions]: https://github.com/lfex/ljson/blob/master/.travis.yml
[github tags]: https://github.com/lfex/ljson/tags
[github tags badge]: https://img.shields.io/github/tag/lfex/ljson.svg
[github downloads]: https://img.shields.io/github/downloads/lfex/ljson/total.svg
[hex badge]: https://img.shields.io/hexpm/v/ljson.svg?maxAge=2592000
[hex package]: https://hex.pm/packages/ljson
[hex downloads]: https://img.shields.io/hexpm/dt/ljson.svg