Source file status.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
type code =
  | OK
  | Cancelled
  | Unknown
  | Invalid_argument
  | Deadline_exceeded
  | Not_found
  | Already_exists
  | Permission_denied
  | Resource_exhausted
  | Failed_precondition
  | Aborted
  | Out_of_range
  | Unimplemented
  | Internal
  | Unavailable
  | Data_loss
  | Unauthenticated
[@@deriving show]

let int_of_code = function
  | OK -> 0
  | Cancelled -> 1
  | Unknown -> 2
  | Invalid_argument -> 3
  | Deadline_exceeded -> 4
  | Not_found -> 5
  | Already_exists -> 6
  | Permission_denied -> 7
  | Resource_exhausted -> 8
  | Failed_precondition -> 9
  | Aborted -> 10
  | Out_of_range -> 11
  | Unimplemented -> 12
  | Internal -> 13
  | Unavailable -> 14
  | Data_loss -> 15
  | Unauthenticated -> 16

let code_of_int = function
  | 0 -> Some OK
  | 1 -> Some Cancelled
  | 2 -> Some Unknown
  | 3 -> Some Invalid_argument
  | 4 -> Some Deadline_exceeded
  | 5 -> Some Not_found
  | 6 -> Some Already_exists
  | 7 -> Some Permission_denied
  | 8 -> Some Resource_exhausted
  | 9 -> Some Failed_precondition
  | 10 -> Some Aborted
  | 11 -> Some Out_of_range
  | 12 -> Some Unimplemented
  | 13 -> Some Internal
  | 14 -> Some Unavailable
  | 15 -> Some Data_loss
  | 16 -> Some Unauthenticated
  | _ -> None

type t = { code : code; message : string option } [@@deriving show]

let v ?message code = { code; message }
let code t = t.code
let message t = Option.map (fun message -> Uri.pct_encode message) t.message

let extract_status headers =
  let code, message =
    match H2.Headers.get headers "grpc-status" with
    | None -> (Unknown, Some "Expected gprc-status header, got nothing")
    | Some s -> (
        match int_of_string_opt s with
        | None ->
            let msg =
              Printf.sprintf "Expected valid gprc-status header, got %s" s
            in
            (Unknown, Some msg)
        | Some i -> (
            match code_of_int i with
            | None ->
                let msg =
                  Printf.sprintf "Expected valid gprc-status code, got %i" i
                in
                (Unknown, Some msg)
            | Some c -> (c, H2.Headers.get headers "grpc-message")))
  in
  v ?message code