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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
open! Core_kernel
include Thing_intf
module Make (Param : sig
val kind : Thing_kind.t
end) =
struct
include Json_object.Utils
include Json_object.Make_kinded_simple (struct
let kind = Thing_kind.to_string Param.kind
end)
type t = Json.t String.Map.t [@@deriving sexp, bin_io]
let module_name = Thing_kind.to_string_long Param.kind
module Id = struct
include Id36
include Identifiable.Make (struct
include Id36
let module_name = sprintf "%s.Id" module_name
let of_string s =
let prefix = sprintf !"%{Thing_kind}_" Param.kind in
Id36.of_string (String.chop_prefix_if_exists s ~prefix)
;;
let to_string = Id36.to_string
end)
end
let id = required_field "id" (string >> Id.of_string)
let url = optional_field "url" uri
let author = required_field "author" (string >> Username.of_string_or_deleted)
let title = required_field "title" string
let description = required_field "description" string
let is_stickied = required_field "stickied" bool
let active_users = required_field "active_user_count" int
let subscribers = required_field "subscribers" int
let creation_time = required_field "created_utc" time
let depth = optional_field "depth" int
let karma_field name = required_field name int
let link_karma = karma_field "link_karma"
let = karma_field "comment_karma"
let awarder_karma = karma_field "awarder_karma"
let awardee_karma = karma_field "awardee_karma"
let total_karma = karma_field "total_karma"
let moderator_reports =
required_field "mod_reports" (Json.get_list Moderator_report.of_json)
;;
let permalink =
required_field
"permalink"
(string
>> Uri.of_string
>> Uri.with_uri ~scheme:(Some "https") ~host:(Some "reddit.com"))
;;
end
module Link = struct
include Make (struct
let kind = Thing_kind.Link
end)
module Id = struct
include (Id : module type of Id)
let of_uri uri =
match Uri.path uri |> String.split ~on:'/' with
| "" :: "r" :: _subreddit :: "comments" :: id :: _rest -> of_string id
| _ -> raise_s [%message "Unexpected Uri format" (uri : Uri_sexp.t)]
;;
end
let score = required_field "score" int
let subreddit = required_field "subreddit" subreddit_name
let domain = required_field "domain" string
end
module Message = Make (struct
let kind = Thing_kind.Message
end)
module Subreddit = struct
include Make (struct
let kind = Thing_kind.Subreddit
end)
let name = required_field "display_name" subreddit_name
end
module User = struct
include Make (struct
let kind = Thing_kind.User
end)
let name = required_field "name" username
let subreddit = required_field "subreddit" Subreddit.of_json
end
module Award = Make (struct
let kind = Thing_kind.Award
end)
module Modmail_conversation = Make (struct
let kind = Thing_kind.Modmail_conversation
end)
module Fullname = struct
module M = struct
type t =
[ `Comment of Comment'.Id.t
| `User of User.Id.t
| `Link of Link.Id.t
| `Message of Message.Id.t
| `Subreddit of Subreddit.Id.t
| `Award of Award.Id.t
| `More_comments of More_comments.Id.t
| `Modmail_conversation of Modmail_conversation.Id.t
]
[@@deriving sexp, bin_io, compare, hash]
let of_string s =
let kind_string, id_string = String.lsplit2_exn s ~on:'_' in
let kind = Thing_kind.of_string kind_string in
let id = Id36.of_string id_string in
Thing_kind.to_polymorphic_tag_uniform kind ~data:id
;;
let to_string t =
let kind, id = Thing_kind.of_polymorphic_tag_with_uniform_data t in
sprintf !"%{Thing_kind}_%{Id36}" kind id
;;
let module_name = "Thing.Fullname"
end
include Identifiable.Make (M)
include M
end
module Poly = struct
type t =
[ `Comment of Comment'.t
| `User of User.t
| `Link of Link.t
| `Message of Message.t
| `Subreddit of Subreddit.t
| `Award of Award.t
| `More_comments of More_comments.t
| `Modmail_conversation of Modmail_conversation.t
]
[@@deriving sexp]
let of_json json =
let kind = Json.find json [ "kind" ] |> Json.get_string |> Thing_kind.of_string in
let data = Json.find json [ "data" ] |> Comment'.of_json in
Thing_kind.to_polymorphic_tag_uniform kind ~data
;;
let fullname t =
let kind, data = Thing_kind.of_polymorphic_tag_with_uniform_data t in
let id = Comment'.id data in
Thing_kind.to_polymorphic_tag_uniform kind ~data:id
;;
end