Current section

Files

Jump to
ewe src ewe internal encoder.gleam
Raw

src/ewe/internal/encoder.gleam

import gleam/bytes_tree
import gleam/http/response
import gleam/int
import gleam/list
/// Encodes an HTTP response into bytes.
///
pub fn encode_response(
response: response.Response(BitArray),
) -> bytes_tree.BytesTree {
bytes_tree.new()
|> bytes_tree.append(encode_status_line(response.status))
|> bytes_tree.append(encode_headers(response.headers))
|> bytes_tree.append(response.body)
}
/// Encodes the HTTP status line and headers of an HTTP response.
///
pub fn encode_response_partially(
response: response.Response(a),
) -> bytes_tree.BytesTree {
bytes_tree.new()
|> bytes_tree.append(encode_status_line(response.status))
|> bytes_tree.append(encode_headers(response.headers))
}
/// Encodes the HTTP status line.
///
fn encode_status_line(status: Int) -> BitArray {
let status_name = status_to_bit_array(status)
let status = int.to_string(status)
<<"HTTP/1.1 ", status:utf8, " ", status_name:bits, "\r\n">>
}
/// Encodes HTTP headers into bytes.
///
fn encode_headers(headers: List(#(String, String))) -> BitArray {
let headers =
list.fold(headers, <<>>, fn(acc, headers) {
let #(key, value) = headers
<<acc:bits, key:utf8, ": ", value:utf8, "\r\n">>
})
<<headers:bits, "\r\n">>
}
/// Maps HTTP status codes to their text descriptions.
///
fn status_to_bit_array(status: Int) -> BitArray {
case status {
100 -> <<"Continue">>
101 -> <<"Switching Protocols">>
102 -> <<"Processing">>
103 -> <<"Early Hints">>
200 -> <<"OK">>
201 -> <<"Created">>
202 -> <<"Accepted">>
203 -> <<"Non-Authoritative Information">>
204 -> <<"No Content">>
205 -> <<"Reset Content">>
206 -> <<"Partial Content">>
207 -> <<"Multi-Status">>
208 -> <<"Already Reported">>
226 -> <<"IM Used">>
300 -> <<"Multiple Choices">>
301 -> <<"Moved Permanently">>
302 -> <<"Found">>
303 -> <<"See Other">>
304 -> <<"Not Modified">>
307 -> <<"Temporary Redirect">>
308 -> <<"Permanent Redirect">>
400 -> <<"Bad Request">>
401 -> <<"Unauthorized">>
403 -> <<"Forbidden">>
404 -> <<"Not Found">>
405 -> <<"Method Not Allowed">>
406 -> <<"Not Acceptable">>
407 -> <<"Proxy Authentication Required">>
408 -> <<"Request Timeout">>
409 -> <<"Conflict">>
410 -> <<"Gone">>
411 -> <<"Length Required">>
412 -> <<"Precondition Failed">>
413 -> <<"Payload Too Large">>
414 -> <<"URI Too Long">>
415 -> <<"Unsupported Media Type">>
416 -> <<"Range Not Satisfiable">>
417 -> <<"Expectation Failed">>
418 -> <<"I'm a teapot">>
421 -> <<"Misdirected Request">>
422 -> <<"Unprocessable Entity">>
423 -> <<"Locked">>
424 -> <<"Failed Dependency">>
425 -> <<"Too Early">>
426 -> <<"Upgrade Required">>
428 -> <<"Precondition Required">>
429 -> <<"Too Many Requests">>
431 -> <<"Request Header Fields Too Large">>
451 -> <<"Unavailable For Legal Reasons">>
500 -> <<"Internal Server Error">>
501 -> <<"Not Implemented">>
502 -> <<"Bad Gateway">>
503 -> <<"Service Unavailable">>
504 -> <<"Gateway Timeout">>
505 -> <<"HTTP Version Not Supported">>
506 -> <<"Variant Also Negotiates">>
507 -> <<"Insufficient Storage">>
508 -> <<"Loop Detected">>
510 -> <<"Not Extended">>
511 -> <<"Network Authentication Required">>
_ -> <<"Unknown HTTP Status">>
}
}