context.gno
1.58 Kb ยท 72 lines
1// Package context provides a minimal implementation of Go context with support
2// for Value and WithValue.
3//
4// Adapted from https://github.com/golang/go/tree/master/src/context/.
5// Copyright 2016 The Go Authors. All rights reserved.
6// Use of this source code is governed by a BSD-style
7// license that can be found in the LICENSE file.
8package context
9
10type Context interface {
11 // Value returns the value associated with this context for key, or nil
12 // if no value is associated with key.
13 Value(key any) any
14}
15
16// Empty returns a non-nil, empty context, similar with context.Background and
17// context.TODO in Go.
18func Empty() Context {
19 return &emptyCtx{}
20}
21
22type emptyCtx struct{}
23
24func (ctx emptyCtx) Value(key any) any {
25 return nil
26}
27
28func (ctx emptyCtx) String() string {
29 return "context.Empty"
30}
31
32type valueCtx struct {
33 parent Context
34 key, val any
35}
36
37func (ctx *valueCtx) Value(key any) any {
38 if ctx.key == key {
39 return ctx.val
40 }
41 return ctx.parent.Value(key)
42}
43
44func stringify(v any) string {
45 switch s := v.(type) {
46 case stringer:
47 return s.String()
48 case string:
49 return s
50 }
51 return "non-stringer"
52}
53
54type stringer interface {
55 String() string
56}
57
58func (c *valueCtx) String() string {
59 return stringify(c.parent) + ".WithValue(" +
60 stringify(c.key) + ", " +
61 stringify(c.val) + ")"
62}
63
64// WithValue returns a copy of parent in which the value associated with key is
65// val.
66func WithValue(parent Context, key, val any) Context {
67 if key == nil {
68 panic("nil key")
69 }
70 // XXX: if !reflect.TypeOf(key).Comparable() { panic("key is not comparable") }
71 return &valueCtx{parent, key, val}
72}