Source file wamp_yojson.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
open Wamp
let remaining_args = function
| [`List args] -> args, []
| [`List args; `Assoc kwArgs] -> args, kwArgs
| _ -> [], []
let msg_of_yojson = function
| `List ((`Int typ) :: content) -> begin
match msgtyp_of_enum typ with
| None -> Result.Error Printf.(sprintf "msg_of_json: invalid msg type %d" typ)
| Some HELLO -> begin
match content with
| [`String uri; `Assoc details] ->
let realm = Uri.of_string uri in
Ok (hello ~realm ~details)
| _ -> Error "msg_of_yojson: HELLO"
end
| Some WELCOME -> begin
match content with
| [`Int id; `Assoc details] ->
Ok (welcome ~id ~details)
| _ -> Error "msg_of_yojson: WELCOME"
end
| Some ABORT -> begin
match content with
| [`Assoc details; `String reason] ->
let reason = Uri.of_string reason in
Ok (abort ~details ~reason)
| _ -> Error "msg_of_yojson: ABORT"
end
| Some GOODBYE -> begin
match content with
| [`Assoc details; `String reason] ->
let reason = Uri.of_string reason in
Ok (goodbye ~details ~reason)
| _ -> Error "msg_of_yojson: GOODBYE"
end
| Some ERROR -> begin
match content with
| `Int reqtype :: `Int reqid :: `Assoc details :: `String uri :: tl ->
let uri = Uri.of_string uri in
let args, kwArgs = remaining_args tl in
Ok (error ~reqtype ~reqid ~details ~error:uri ~args ~kwArgs)
| _ -> Error "msg_of_yojson: ERROR"
end
| Some PUBLISH -> begin
match content with
| `Int reqid :: `Assoc options :: `String topic :: tl ->
let topic = Uri.of_string topic in
let args, kwArgs = remaining_args tl in
Ok (publish ~reqid ~options ~topic ~args ~kwArgs)
| _ -> Error "msg_of_yojson: PUBLISH"
end
| Some PUBLISHED -> begin
match content with
| [`Int reqid; `Int id] ->
Ok (published ~reqid ~id)
| _ -> Error "msg_of_yojson: PUBLISHED"
end
| Some SUBSCRIBE -> begin
match content with
| [`Int reqid; `Assoc options; `String topic] ->
let topic = Uri.of_string topic in
Ok (subscribe reqid options topic)
| _ -> Error "msg_of_yojson: PUBLISH"
end
| Some SUBSCRIBED -> begin
match content with
| [`Int reqid; `Int id] ->
Ok (subscribed ~reqid ~id)
| _ -> Error "msg_of_yojson: SUBSCRIBED"
end
| Some UNSUBSCRIBE -> begin
match content with
| [`Int reqid; `Int id] ->
Ok (unsubscribe ~reqid ~id)
| _ -> Error "msg_of_yojson: UNSUBSCRIBE"
end
| Some UNSUBSCRIBED -> begin
match content with
| [`Int reqid] -> Ok (unsubscribed reqid)
| _ -> Error "msg_of_yojson: UNSUBSCRIBED"
end
| Some EVENT -> begin
match content with
| `Int subid :: `Int pubid :: `Assoc details :: tl ->
let args, kwArgs = remaining_args tl in
Ok (event ~subid ~pubid ~details ~args ~kwArgs)
| _ -> Error "msg_of_yojson: EVENT"
end
end
| #Yojson.Safe.json as json -> Error Yojson.Safe.(to_string json)
let msg_to_yojson = function
| Hello { realm; details } ->
`List [`Int (msgtyp_to_enum HELLO); `String (Uri.to_string realm); `Assoc details]
| Welcome { id; details } ->
`List [`Int (msgtyp_to_enum WELCOME); `Int id; `Assoc details ]
| Abort { details; reason } ->
`List [`Int (msgtyp_to_enum ABORT); `Assoc details; `String (Uri.to_string reason) ]
| Goodbye { details; reason } ->
`List [`Int (msgtyp_to_enum GOODBYE); `Assoc details; `String (Uri.to_string reason) ]
| Error { reqtype; reqid; details; error; args; kwArgs } ->
`List [`Int (msgtyp_to_enum ERROR); `Int reqtype; `Int reqid; `Assoc details; `String (Uri.to_string error); `List args; `Assoc kwArgs]
| Publish { reqid; options; topic; args; kwArgs } ->
`List [`Int (msgtyp_to_enum PUBLISH); `Int reqid; `Assoc options; `String (Uri.to_string topic); `List args; `Assoc kwArgs]
| Published { reqid; id } ->
`List [`Int (msgtyp_to_enum PUBLISHED); `Int reqid; `Int id]
| Subscribe { reqid; options; topic } ->
`List [`Int (msgtyp_to_enum SUBSCRIBE); `Int reqid; `Assoc options; `String (Uri.to_string topic)]
| Subscribed { reqid; id } ->
`List [`Int (msgtyp_to_enum SUBSCRIBED); `Int reqid; `Int id]
| Unsubscribe { reqid; id } ->
`List [`Int (msgtyp_to_enum UNSUBSCRIBE); `Int reqid; `Int id]
| Unsubscribed reqid ->
`List [`Int (msgtyp_to_enum UNSUBSCRIBED); `Int reqid]
| Event { subid; pubid; details; args; kwArgs } ->
`List [`Int (msgtyp_to_enum EVENT); `Int subid; `Int pubid; `Assoc details; `List args; `Assoc kwArgs]
let hello realm roles =
let roles = ListLabels.map roles ~f:(fun r -> string_of_role r, `Assoc []) in
hello ~realm ~details:["roles", `Assoc roles]
let subscribe ?(reqid=Random.bits ()) ?(options=[]) topic =
reqid, (subscribe reqid options topic)