native_http.bend
bend-trace-context@0.2.0.0 · 156 lines · 17 definitions
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
27import Base
28import bend-trace-context@0.2.0.0/trace_context.bend as TC
29
30
31
32def HeaderMap() -> Data:
33 Map<&2, List<&2, String>>
34
35
36
37type Outbound is Data:
38 Outbound{sent: TC.Sent, headers: Map<&2, List<&2, String>>}
39
40
41
42
43def Headers.push(+name: String, values: List<&2, String>, fields: List<&2, TC.Header>) -> List<&2, TC.Header>:
44 match values:
45 case Nil{}:
46 fields
47 case Con{value, rest}:
48 Headers.push(name, rest, Con{TC.Header{name, value}, fields})
49
50
51def Headers.gather(entries: List<&2, Sigma<&2, &2, String, _ => List<&2, String>>>, fields: List<&2, TC.Header>) ->
52 List<&2, TC.Header>:
53 match entries:
54 case Nil{}:
55 fields
56 case Con{Tuple{name, values}, rest}:
57 Headers.gather(rest, Headers.push(name, values, fields))
58
59
60
61
62
63def carrier(headers: HeaderMap()) -> List<&2, TC.Header>:
64 List.reverse(&2, TC.Header, Headers.gather(Map.to_list(&2, List<&2, String>, headers), Nil{}))
65
66
67def Headers.values(+headers: HeaderMap(), name: String) -> List<&2, String>:
68 Pair.snd(HeaderMap(), List<&2, String>, Map.get(List<&2, String>, Nil{}, headers, name))
69
70
71def Headers.add(+headers: HeaderMap(), header: TC.Header) -> HeaderMap():
72 match header:
73 case TC.Header{+name, value}:
74 Map.set(&2, List<&2, String>, headers, name, Con{value, Headers.values(headers, name)})
75
76
77
78def Headers.write(fields: List<&2, TC.Header>, +headers: HeaderMap()) -> HeaderMap():
79 match fields:
80 case Nil{}:
81 headers
82 case Con{header, rest}:
83 Headers.write(rest, Headers.add(headers, header))
84
85
86
87
88
89
90
91def headers(carrier: List<&2, TC.Header>) -> HeaderMap():
92 Headers.write(List.reverse(&2, TC.Header, carrier), Map.new(&2, List<&2, String>))
93
94
95
96
97
98def continue_or_start_with(~S: Type, ~read: S -> IO(S & Result<&1, &1, U32 & String, U32>), source: S,
99 +limits: TC.Limits, headers: HeaderMap(), base: Maybe<&2, TC.BaseContext>, reception: TC.Reception,
100 sampling: TC.Sampling, +policy: TC.FailurePolicy) -> IO(S & TC.FailurePolicy.result(policy, TC.Service)):
101 TC.Context.continue_or_start_with(~S, ~read, source, TC.Context.extract(limits, carrier(headers), base), reception,
102 sampling, policy)
103
104
105
106def Headers.outbound(+sent: TC.Sent) -> Outbound:
107 Outbound{sent, headers(TC.Sent.carrier(sent))}
108
109
110def Headers.strict(result: Result<&2, &2, TC.GenerationError, TC.Sent>) ->
111 Result<&2, &2, TC.GenerationError, Outbound>:
112 match result:
113 case Fail{error}:
114 Fail{error}
115 case Done{sent}:
116 Done{Headers.outbound(sent)}
117
118
119def Headers.written(policy: TC.FailurePolicy, result: TC.FailurePolicy.result(policy, TC.Sent)) ->
120 TC.FailurePolicy.result(policy, Outbound):
121 match policy:
122 case TC.Lenient{}:
123 Headers.outbound(result)
124 case TC.Strict{}:
125 Headers.strict(result)
126
127
128def Headers.written.done(-S: Type, +policy: TC.FailurePolicy, done: S & TC.FailurePolicy.result(policy, TC.Sent)) ->
129 S & TC.FailurePolicy.result(policy, Outbound):
130 (source, result) = done
131 (source, Headers.written(policy, result))
132
133
134
135
136
137
138
139def send_with(~S: Type, ~read: S -> IO(S & Result<&1, &1, U32 & String, U32>), source: S, +limits: TC.Limits,
140 service: TC.Service, sampling: TC.Sampling, +policy: TC.FailurePolicy, headers: HeaderMap()) ->
141 IO(S & TC.FailurePolicy.result(policy, Outbound)):
142 IO.bind(S & TC.FailurePolicy.result(policy, TC.Sent), S & TC.FailurePolicy.result(policy, Outbound),
143 TC.Context.send_with(~S, ~read, source, limits, service, sampling, policy, carrier(headers)),
144 done => IO.pure(S & TC.FailurePolicy.result(policy, Outbound), Headers.written.done(S, policy, done)))
145
146
147def Outbound.sent(outbound: Outbound) -> TC.Sent:
148 match outbound:
149 case Outbound{sent, headers}:
150 sent
151
152
153def Outbound.headers(outbound: Outbound) -> HeaderMap():
154 match outbound:
155 case Outbound{sent, headers}:
156 headers