-
Notifications
You must be signed in to change notification settings - Fork 0
/
form.gleam
76 lines (73 loc) · 1.82 KB
/
form.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
import gleam/dynamic.{Dynamic}
import gleam/result
pub type FormDecodeError {
UnexpectedFormat(List(dynamic.DecodeError))
}
/// Parses form encoded data
///
/// ### Examples
///
/// ```gleam
/// pub type Note {
/// Note(id: Int, title: String, content: String)
/// }
/// pub fn decode(body: String) {
/// let decoder =
/// dynamic.decode3(
/// Note,
/// dynamic.field("id", of: dynamic.int),
/// dynamic.field("title", of: dynamic.string),
/// dynamic.field("content", of: dynamic.string),
/// )
/// form.decode(body, decoder)
/// }
///
/// ```
/// > decode("id=1&title=Hello&content=World")
/// Ok(Note(1, "Hello", "World"))
///
/// You can couple this with a request middleware to parse the body of a request
///
/// ```gleam
///pub fn create_decoder(
/// handler: Service(Result(Note, form.FormDecodeError), assigns, session, res),
///) -> Service(BitString, assigns, session, res) {
/// fn(req: Request(BitString, assigns, session)) -> Response(res) {
/// request.map(
/// req,
/// fn(body) {
/// body
/// |> bit_string.to_string()
/// |> result.unwrap("")
/// |> decode()
/// },
/// )
/// |> handler()
/// }
///}
///...
///router.get(
/// "/",
/// {
/// use req: Request(Result(Note, form.FormDecodeError), assigns, session) <- create_decoder
/// case req.body {
/// Ok(note) -> send(202, note.content)
/// t -> {
/// io.debug(t)
/// send(400, "Bad Request")
/// }
/// }
/// },
///)
/// ```
///
pub fn decode(body: String, decoder: dynamic.Decoder(t)) {
let decoded =
body
|> decode_to_dynamic()
|> dynamic.from()
decoder(decoded)
|> result.map_error(UnexpectedFormat)
}
@external(erlang, "gleam_cowboy_native", "parse_query_string")
fn decode_to_dynamic(a: String) -> Result(Dynamic, FormDecodeError)