package reddit_api_kernel

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file listing.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
open! Core_kernel
module Page_id = String

module Pagination = struct
  type t =
    | Before of Page_id.t
    | After of Page_id.t
  [@@deriving sexp]
end

type 'a t =
  { children : 'a list
  ; after : Page_id.t option
  }
[@@deriving sexp, fields]

let map t ~f = { t with children = List.map t.children ~f }

let of_json convert_element json =
  let fail s = raise_s [%message s (json : Json.t)] in
  let assoc =
    match json with
    | `O list -> list
    | _ -> fail "Expected JSON map when creating [Listing.t]"
  in
  let data =
    match List.Assoc.find assoc "data" ~equal:String.equal with
    | Some data -> data
    | None -> fail "Missing field \"data\""
  in
  let data =
    match data with
    | `O list -> list
    | _ -> fail "Expected \"data\" to be an object"
  in
  let data =
    match String.Map.of_alist data with
    | `Ok map -> map
    | `Duplicate_key key -> fail (sprintf "Duplicate key: \"%s\"" key)
  in
  let children =
    match Map.find data "children" with
    | Some (`A l) -> l
    | Some _ -> fail "Expected \"children\" to be a list"
    | None -> fail "Missing key \"children\""
  in
  let children = List.map children ~f:convert_element in
  let after =
    match Map.find data "after" with
    | None | Some `Null -> None
    | Some (`String s) -> Some (Page_id.of_string s)
    | Some _ -> fail "Expected \"after\" to be a string"
  in
  { children; after }
;;