adam@1
|
1 open Json
|
adam@1
|
2
|
adam@3
|
3 (* Example from http://en.wikipedia.org/wiki/JSON *)
|
adam@1
|
4
|
adam@3
|
5 type address = {StreetAddress : string,
|
adam@3
|
6 City : string,
|
adam@3
|
7 State : string,
|
adam@3
|
8 PostalCode : string}
|
adam@3
|
9
|
ezyang@22
|
10 type phoneType = variant [Mobile = string,
|
ezyang@22
|
11 LandLine = unit,
|
ezyang@22
|
12 Secret = unit]
|
ezyang@22
|
13
|
ezyang@22
|
14 type phoneNumber = {Type_ : phoneType,
|
adam@3
|
15 Number : string}
|
adam@3
|
16
|
adam@3
|
17 type person = {FirstName : string,
|
adam@3
|
18 LastName : string,
|
adam@3
|
19 Age : int,
|
adam@3
|
20 Address : address,
|
adam@3
|
21 PhoneNumber : list phoneNumber}
|
adam@3
|
22
|
adam@3
|
23 val sample : person = {FirstName = "Larry",
|
adam@3
|
24 LastName = "Lambda",
|
adam@3
|
25 Age = 42,
|
adam@3
|
26 Address = {StreetAddress = "99 Confluence Circle",
|
adam@3
|
27 City = "Hoserville",
|
adam@3
|
28 State = "QQ",
|
adam@3
|
29 PostalCode = "66666"},
|
ezyang@22
|
30 PhoneNumber = {Type_ = make [#Mobile] "Verizon", Number = "1234"}
|
ezyang@22
|
31 :: {Type_ = make [#Secret] (), Number = "ssssh"}
|
adam@3
|
32 :: []}
|
adam@3
|
33
|
adam@3
|
34 val json_address : json address = json_record {StreetAddress = "streetAddress",
|
adam@3
|
35 City = "city",
|
adam@3
|
36 State = "state",
|
adam@3
|
37 PostalCode = "postalCode"}
|
adam@3
|
38
|
ezyang@22
|
39 val json_phoneType : json phoneType = json_variant {Mobile = "mobile",
|
ezyang@22
|
40 LandLine = "landline",
|
ezyang@22
|
41 Secret = "secret"}
|
ezyang@22
|
42
|
adam@3
|
43 val json_phoneNumber : json phoneNumber = json_record {Type_ = "type",
|
adam@3
|
44 Number = "number"}
|
adam@3
|
45
|
adam@3
|
46 val json_person : json person = json_record {FirstName = "firstName",
|
adam@3
|
47 LastName = "lastName",
|
adam@3
|
48 Age = "age",
|
adam@3
|
49 Address = "address",
|
adam@3
|
50 PhoneNumber = "phoneNumber"}
|
adam@3
|
51
|
adam@3
|
52 fun renderPerson (p : person) = <xml>
|
adam@3
|
53 <b>First name:</b> {[p.FirstName]}<br/>
|
adam@3
|
54 <b>Last name:</b> {[p.LastName]}<br/>
|
adam@3
|
55 <b>Age:</b> {[p.Age]}<br/>
|
adam@3
|
56 <b>Street address:</b> {[p.Address.StreetAddress]}<br/>
|
adam@3
|
57 <b>City:</b> {[p.Address.City]}<br/>
|
adam@3
|
58 <b>State:</b> {[p.Address.State]}<br/>
|
adam@3
|
59 <b>Postal code:</b> {[p.Address.PostalCode]}<br/>
|
ezyang@23
|
60 <!-- <b>Phone numbers:</b> {List.mapX (fn pn => <xml>{[pn.Number]}; </xml>) p.PhoneNumber}<br/> -->
|
adam@3
|
61 </xml>
|
adam@3
|
62
|
adam@3
|
63 fun parse r = return <xml><body>
|
adam@3
|
64 {renderPerson (fromJson r.Text)}
|
adam@3
|
65 </body></xml>
|
adam@3
|
66
|
adam@3
|
67 fun main () = return <xml><body>
|
adam@3
|
68 <h1>Json parsing adventure!</h1>
|
adam@3
|
69
|
adam@3
|
70 <hr/>
|
adam@3
|
71 <h2>Free sample</h2>
|
adam@3
|
72
|
adam@3
|
73 {[toJson sample]}
|
adam@3
|
74 <hr/>
|
adam@3
|
75
|
adam@3
|
76 <h2>Parse your own</h2>
|
adam@3
|
77 <form>
|
adam@3
|
78 <textarea{#Text} rows={10} cols={80}/><br/>
|
adam@3
|
79 <submit value="Parse" action={parse}/>
|
adam@3
|
80 </form>
|
adam@3
|
81 </body></xml>
|
ezyang@23
|
82
|
ezyang@23
|
83 structure God = Json.Recursive(struct
|
ezyang@23
|
84 con t a = variant [Fun = string * list a,
|
ezyang@23
|
85 Var = string]
|
ezyang@23
|
86
|
ezyang@23
|
87 fun json_t [a] (_ : json a) : json (t a) =
|
ezyang@23
|
88 let
|
ezyang@23
|
89 val json_fun : json (string * list a) = json_record ("1", "2")
|
ezyang@23
|
90 in
|
ezyang@23
|
91 json_variant {Fun = "Fun", Var = "Var"}
|
ezyang@23
|
92 end
|
ezyang@23
|
93 end)
|
ezyang@23
|
94
|
ezyang@23
|
95 fun renderGod (God.Rec g) =
|
ezyang@23
|
96 match g
|
ezyang@23
|
97 {Fun = fn (s, gs) => <xml>
|
ezyang@23
|
98 <b>Main god:</b> {[s]}<br/>
|
ezyang@23
|
99 <b>Subgods:</b> <ul>
|
ezyang@23
|
100 {List.mapX (fn g' => <xml><li>{renderGod g'}</li></xml>) gs}
|
ezyang@23
|
101 </ul>
|
ezyang@23
|
102 </xml>,
|
ezyang@23
|
103 Var = fn s => <xml>
|
ezyang@23
|
104 <b>Var:</b> {[s]}
|
ezyang@23
|
105 </xml>}
|
ezyang@23
|
106
|
ezyang@23
|
107 fun parseGod r = return <xml><body>
|
ezyang@23
|
108 <h2>Beautified</h2>
|
ezyang@23
|
109 {renderGod (fromJson r.Text)}
|
ezyang@23
|
110
|
ezyang@23
|
111 <h2>Round-tripped</h2>
|
ezyang@23
|
112 {[toJson (fromJson r.Text : God.r)]}
|
ezyang@23
|
113 </body></xml>
|
ezyang@23
|
114
|
ezyang@23
|
115 fun godMain () = return <xml><body>
|
ezyang@23
|
116 <h1>Parse ye gods</h1>
|
ezyang@23
|
117
|
ezyang@23
|
118 <form>
|
ezyang@23
|
119 <textarea{#Text} rows={10} cols={80}/><br/>
|
ezyang@23
|
120 <submit value="Parse" action={parseGod}/>
|
ezyang@23
|
121 </form>
|
ezyang@23
|
122 </body></xml>
|