1 | // This module defines the Context type, which carries deadlines, cancellation signals, |
2 | // and other request-scoped values across API boundaries and between processes. |
3 | // Based on: https://github.com/golang/go/tree/master/src/context |
4 | // Last commit: https://github.com/golang/go/commit/52bf14e0e8bdcd73f1ddfb0c4a1d0200097d3ba2 |
5 | module context |
6 | |
7 | import time |
8 | |
9 | const ( |
10 | cancel_context_key = Key('context.CancelContext') |
11 | |
12 | // canceled is the error returned by Context.err when the context is canceled. |
13 | canceled = error('context canceled') |
14 | |
15 | // deadline_exceeded is the error returned by Context.err when the context's |
16 | // deadline passes. |
17 | deadline_exceeded = error('context deadline exceeded') |
18 | ) |
19 | |
20 | // Key represents the type for the ValueContext key |
21 | pub type Key = bool | f32 | f64 | i16 | i64 | i8 | int | string | u16 | u32 | u64 | u8 | voidptr |
22 | |
23 | // Any represents a generic type for the ValueContext |
24 | pub interface Any {} |
25 | |
26 | // `Context` is an interface that defined the minimum required functionality |
27 | // for a Context. |
28 | // |
29 | // `deadline()` returns the time when work done on behalf of this context |
30 | // should be canceled. deadline returns none when no deadline is |
31 | // set. Successive calls to deadline return the same results. |
32 | // |
33 | // `value(key)` returns an Optional that wraps the value associated with this context for key. |
34 | // It returns none if no value is associated with key. Successive calls to Value with |
35 | // the same key returns the same result. |
36 | // |
37 | // Use context values only for request-scoped data that transits |
38 | // processes and API boundaries, not for passing optional parameters to |
39 | // functions. |
40 | // |
41 | // A key identifies a specific value in a Context. Functions that wish |
42 | // to store values in Context typically allocate a key in a global |
43 | // variable then use that key as the argument to context.with_value and |
44 | // Context.value. A key can be any type that supports equality; |
45 | // modules should define keys as an unexported type to avoid |
46 | // collisions. |
47 | // |
48 | // `done()` returns a channel that's closed when work done on behalf of this |
49 | // context should be canceled. done may return a closed channel if this context can |
50 | // never be canceled. Successive calls to done return the same value. |
51 | // The close of the done channel may happen asynchronously, |
52 | // after the cancel function returns. |
53 | // |
54 | // with_cancel arranges for done to be closed when cancel is called; |
55 | // with_deadline arranges for done to be closed when the deadline |
56 | // expires; with_timeout arranges for done to be closed when the timeout |
57 | // elapses. |
58 | // |
59 | // `err()` returns an IError based on some conditions |
60 | // If done is not yet closed, err returns none. |
61 | // If done is closed, err returns a non-none error explaining why: |
62 | // canceled if the context was canceled |
63 | // or deadline_exceeded if the context's deadline passed. |
64 | // After err returns a non-none error, successive calls to err return the same error. |
65 | pub interface Context { |
66 | deadline() ?time.Time |
67 | value(key Key) ?Any |
68 | mut: |
69 | done() chan int |
70 | err() IError |
71 | } |
72 | |
73 | // str returns the `str` method of the corresponding Context struct |
74 | pub fn (ctx &Context) str() string { |
75 | // since `Context` is an interface we have to manually match every possible |
76 | // type that implements `Context` if we want to use a `Context` as a field in a struct |
77 | // since the `Context` interface has to implement its own `str` method. |
78 | match ctx { |
79 | BackgroundContext { |
80 | return ctx.str() |
81 | } |
82 | EmptyContext { |
83 | return ctx.str() |
84 | } |
85 | TodoContext { |
86 | return ctx.str() |
87 | } |
88 | CancelContext { |
89 | return ctx.str() |
90 | } |
91 | TimerContext { |
92 | return ctx.str() |
93 | } |
94 | ValueContext { |
95 | return ctx.str() |
96 | } |
97 | else { |
98 | return context_name(ctx) |
99 | } |
100 | } |
101 | } |
102 | |
103 | fn context_name(ctx Context) string { |
104 | return typeof(ctx) |
105 | } |