annotate tests/testJson.ur @ 30:4e673b535434

Optimizing JSON generation
author Adam Chlipala <adam@chlipala.net>
date Thu, 04 Dec 2014 19:52:51 -0500
parents 9d6b931fbd13
children
rev   line source
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>