about summary refs log tree commit diff stats
path: root/src/loader/headers.nim
blob: 5e61fded7975c2462b9ae492661b1402132aecf0 (plain) (blame)
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
119
import tables

import bindings/quickjs
import js/error
import js/fromjs
import js/javascript
import utils/twtstr

type
  Headers* = ref object
    table* {.jsget.}: Table[string, seq[string]]

  HeadersInitType = enum
    HEADERS_INIT_SEQUENCE, HEADERS_INIT_TABLE

  HeadersInit* = object
    case t: HeadersInitType
    of HEADERS_INIT_SEQUENCE:
      s: seq[(string, string)]
    of HEADERS_INIT_TABLE:
      tab: Table[string, string]

jsDestructor(Headers)

proc fromJS2*(ctx: JSContext, val: JSValue, res: var JSResult[HeadersInit]) =
  if JS_IsUndefined(val) or JS_IsNull(val):
    res.err(nil)
    return
  if isSequence(ctx, val):
    let x = fromJS[seq[(string, string)]](ctx, val)
    if x.isSome:
      res.ok(HeadersInit(t: HEADERS_INIT_SEQUENCE, s: x.get))
  else:
    let x = fromJS[Table[string, string]](ctx, val)
    if x.isSome:
      res.ok(HeadersInit(t: HEADERS_INIT_TABLE, tab: x.get))

proc fill*(headers: Headers, s: seq[(string, string)]) =
  for (k, v) in s:
    if k in headers.table:
      headers.table[k].add(v)
    else:
      headers.table[k] = @[v]

proc fill*(headers: Headers, tab: Table[string, string]) =
  for k, v in tab:
    if k in headers.table:
      headers.table[k].add(v)
    else:
      headers.table[k] = @[v]

proc fill*(headers: Headers, init: HeadersInit) =
  if init.t == HEADERS_INIT_SEQUENCE:
    headers.fill(init.s)
  else: # table
    headers.fill(init.tab)

func newHeaders*(): Headers =
  return Headers()

func newHeaders(obj = none(HeadersInit)): Headers {.jsctor.} =
  let headers = Headers()
  if obj.isSome:
    headers.fill(obj.get)
  return headers

func newHeaders*(table: openArray[(string, string)]): Headers =
  let headers = Headers()
  for (k, v) in table:
    let k = k.toHeaderCase()
    headers.table.withValue(k, vs):
      vs[].add(v)
    do:
      headers.table[k] = @[v]
  return headers

func newHeaders*(table: Table[string, string]): Headers =
  let headers = Headers()
  for k, v in table:
    let k = k.toHeaderCase()
    headers.table.withValue(k, vs):
      vs[].add(v)
    do:
      headers.table[k] = @[v]
  return headers

func clone*(headers: Headers): Headers =
  return Headers(
    table: headers.table
  )

proc add*(headers: Headers, k, v: string) =
  let k = k.toHeaderCase()
  headers.table.withValue(k, p):
    p[].add(v)
  do:
    headers.table[k] = @[v]

proc `[]=`*(headers: Headers, k: static string, v: string) =
  const k = k.toHeaderCase()
  headers.table[k] = @[v]

func `[]`*(headers: Headers, k: static string): string =
  const k = k.toHeaderCase()
  return headers.table[k][0]

func contains*(headers: Headers, k: static string): bool =
  const k = k.toHeaderCase()
  return k in headers.table

func getOrDefault*(headers: Headers, k: static string, default = ""): string =
  const k = k.toHeaderCase()
  headers.table.withValue(k, p):
    return p[][0]
  do:
    return default

proc addHeadersModule*(ctx: JSContext) =
  ctx.registerType(Headers)