check content type

This commit is contained in:
lewdum 2024-10-22 18:50:39 -03:00
parent 16d3936c06
commit faba419c39
No known key found for this signature in database
2 changed files with 32 additions and 5 deletions

View file

@ -10,6 +10,8 @@ pub type Client {
pub type Error {
BadInstance
FetchError(error: Dynamic)
ResponseError(status: Int)
UnexpectedStatus(status: Int)
UnexpectedContentType(content_type: String)
MissingContentType
DecodeError(error: DecodeError)
}

View file

@ -3,7 +3,9 @@ import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
import gleam/httpc
import gleam/json
import gleam/pair
import gleam/result
import gleam/string
import apkallone.{type Client, type Error}
@ -22,14 +24,14 @@ pub fn prepare_request(
}
pub fn send_request(req: Request(String)) -> Result(Response(String), Error) {
use req <- result.try(
use res <- result.try(
httpc.send(req)
|> result.map_error(apkallone.FetchError),
)
case req.status {
200 -> Ok(req)
other -> Error(apkallone.ResponseError(other))
case res.status {
200 -> Ok(res)
other -> Error(apkallone.UnexpectedStatus(other))
}
}
@ -37,7 +39,30 @@ pub fn decode_response(
res: Response(String),
decoder: Decoder(a),
) -> Result(a, Error) {
use <- require_content_type(res, "application/json")
res.body
|> json.decode(decoder)
|> result.map_error(apkallone.DecodeError)
}
fn require_content_type(
res: Response(String),
expected_type: String,
fun: fn() -> Result(a, Error),
) -> Result(a, Error) {
use actual_type <- result.try(
response.get_header(res, "content-type")
|> result.replace_error(apkallone.MissingContentType),
)
let actual_type =
string.split_once(actual_type, on: ";")
|> result.map(pair.first)
|> result.unwrap(or: actual_type)
case actual_type == expected_type {
True -> fun()
False -> Error(apkallone.UnexpectedContentType(actual_type))
}
}