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}