-
Notifications
You must be signed in to change notification settings - Fork 1
/
api_response.gleam
118 lines (100 loc) · 3.04 KB
/
api_response.gleam
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
import gleam/dynamic.{type Decoder}
import gleam/http.{type Header}
import gleam/http/response.{type Response, Response}
import gleam/json
import gleam/result
import glitch/error.{type TwitchError, ResponseDecodeError, ResponseError}
pub opaque type TwitchApiResponse(data) {
TwitchApiResponse(Response(data))
}
type TwitchErrorResponse {
TwitchErrorResponse(status: Int, message: String)
}
pub fn of_http_response(response: Response(String)) -> TwitchApiResponse(String) {
TwitchApiResponse(response)
}
fn get_http_response(api_response: TwitchApiResponse(data)) -> Response(data) {
case api_response {
TwitchApiResponse(response) -> response
}
}
pub fn get_body(api_response: TwitchApiResponse(data)) -> data {
get_http_response(api_response).body
}
pub fn get_headers(api_response: TwitchApiResponse(data)) -> List(Header) {
let http_response = get_http_response(api_response)
http_response.headers
}
fn error_decoder() -> Decoder(TwitchErrorResponse) {
dynamic.decode2(
TwitchErrorResponse,
dynamic.field("status", dynamic.int),
dynamic.field("message", dynamic.string),
)
}
pub fn get_data(
api_response: TwitchApiResponse(String),
data_decoder: Decoder(data),
) -> Result(data, TwitchError) {
let body = get_body(api_response)
let error = json.decode(body, error_decoder())
case error {
Ok(TwitchErrorResponse(status, message)) ->
Error(ResponseError(status, message))
_ ->
body
|> json.decode(
dynamic.any([data_decoder, dynamic.field("data", data_decoder)]),
)
|> result.map_error(ResponseDecodeError)
}
}
pub fn get_list_data(
api_response: TwitchApiResponse(String),
data_decoder: Decoder(data),
) -> Result(List(data), TwitchError) {
let body = get_body(api_response)
let error = json.decode(body, error_decoder())
case error {
Ok(TwitchErrorResponse(status, message)) ->
Error(ResponseError(status, message))
_ ->
body
|> json.decode(
dynamic.any([
dynamic.field("data", dynamic.list(of: data_decoder)),
dynamic.list(of: data_decoder),
]),
)
|> result.map_error(ResponseDecodeError)
}
}
pub type EventSubData(data) {
EventSubData(data: data, total: Int, total_cost: Int, max_total_cost: Int)
}
fn eventsub_data_decoder(
data_decoder: Decoder(data),
) -> Decoder(EventSubData(List(data))) {
dynamic.decode4(
EventSubData,
dynamic.field("data", dynamic.list(data_decoder)),
dynamic.field("total", dynamic.int),
dynamic.field("total_cost", dynamic.int),
dynamic.field("max_total_cost", dynamic.int),
)
}
pub fn get_eventsub_data(
api_response: TwitchApiResponse(String),
data_decoder: Decoder(data),
) -> Result(EventSubData(List(data)), TwitchError) {
let body = get_body(api_response)
let error = json.decode(body, error_decoder())
case error {
Ok(TwitchErrorResponse(status, message)) ->
Error(ResponseError(status, message))
_ ->
body
|> json.decode(eventsub_data_decoder(data_decoder))
|> result.map_error(ResponseDecodeError)
}
}