package ginctx import ( "fmt" "sync/atomic" "github.com/gin-gonic/gin" ) func Get[T any](c *gin.Context, key string) (T, error) { var zero T v, ok := c.Get(key) if !ok { return zero, fmt.Errorf("Get: %q not found", key) } typed, ok := v.(T) if !ok { return zero, fmt.Errorf("Get: %q has wrong type", key) } return typed, nil } func GetAtomic[T any](c *gin.Context, key string) (T, error) { var zero T // retrieve *atomic.Value stored in context av, err := Get[*atomic.Value](c, key) if err != nil { return zero, err } if av == nil { return zero, fmt.Errorf("GetAtomic: atomic.Value pointer is nil for key %q", key) } // load current value from atomic.Value raw := av.Load() if raw == nil { return zero, fmt.Errorf("GetAtomic: value is nil for key %q", key) } typed, ok := raw.(T) if !ok { return zero, fmt.Errorf("GetAtomic: value for key %q has wrong type", key) } return typed, nil } func GetAtomicOrNormal[T any](c *gin.Context, key string) (T, error) { var zero T v, ok := c.Get(key) if !ok { return zero, fmt.Errorf("GetAny: %q not found", key) } // If it's an *atomic.Value, load from it. if av, ok := v.(*atomic.Value); ok { raw := av.Load() if raw == nil { return zero, fmt.Errorf("GetAny: atomic value for %q is nil", key) } typed, ok := raw.(T) if !ok { return zero, fmt.Errorf("GetAny: atomic value for %q has wrong type", key) } return typed, nil } // Otherwise try direct assertion. typed, ok := v.(T) if !ok { return zero, fmt.Errorf("GetAny: %q has wrong type", key) } return typed, nil }