summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/exp/slog/json_handler.go
diff options
context:
space:
mode:
authorLibravatar Terin Stock <terinjokes@gmail.com>2025-03-09 17:47:56 +0100
committerLibravatar Terin Stock <terinjokes@gmail.com>2025-03-10 01:59:49 +0100
commit3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch)
treef61faa581feaaeaba2542b9f2b8234a590684413 /vendor/golang.org/x/exp/slog/json_handler.go
parent[chore] update URLs to forked source (diff)
downloadgotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz
[chore] remove vendor
Diffstat (limited to 'vendor/golang.org/x/exp/slog/json_handler.go')
-rw-r--r--vendor/golang.org/x/exp/slog/json_handler.go336
1 files changed, 0 insertions, 336 deletions
diff --git a/vendor/golang.org/x/exp/slog/json_handler.go b/vendor/golang.org/x/exp/slog/json_handler.go
deleted file mode 100644
index 157ada869..000000000
--- a/vendor/golang.org/x/exp/slog/json_handler.go
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package slog
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "strconv"
- "time"
- "unicode/utf8"
-
- "golang.org/x/exp/slog/internal/buffer"
-)
-
-// JSONHandler is a Handler that writes Records to an io.Writer as
-// line-delimited JSON objects.
-type JSONHandler struct {
- *commonHandler
-}
-
-// NewJSONHandler creates a JSONHandler that writes to w,
-// using the given options.
-// If opts is nil, the default options are used.
-func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler {
- if opts == nil {
- opts = &HandlerOptions{}
- }
- return &JSONHandler{
- &commonHandler{
- json: true,
- w: w,
- opts: *opts,
- },
- }
-}
-
-// Enabled reports whether the handler handles records at the given level.
-// The handler ignores records whose level is lower.
-func (h *JSONHandler) Enabled(_ context.Context, level Level) bool {
- return h.commonHandler.enabled(level)
-}
-
-// WithAttrs returns a new JSONHandler whose attributes consists
-// of h's attributes followed by attrs.
-func (h *JSONHandler) WithAttrs(attrs []Attr) Handler {
- return &JSONHandler{commonHandler: h.commonHandler.withAttrs(attrs)}
-}
-
-func (h *JSONHandler) WithGroup(name string) Handler {
- return &JSONHandler{commonHandler: h.commonHandler.withGroup(name)}
-}
-
-// Handle formats its argument Record as a JSON object on a single line.
-//
-// If the Record's time is zero, the time is omitted.
-// Otherwise, the key is "time"
-// and the value is output as with json.Marshal.
-//
-// If the Record's level is zero, the level is omitted.
-// Otherwise, the key is "level"
-// and the value of [Level.String] is output.
-//
-// If the AddSource option is set and source information is available,
-// the key is "source"
-// and the value is output as "FILE:LINE".
-//
-// The message's key is "msg".
-//
-// To modify these or other attributes, or remove them from the output, use
-// [HandlerOptions.ReplaceAttr].
-//
-// Values are formatted as with an [encoding/json.Encoder] with SetEscapeHTML(false),
-// with two exceptions.
-//
-// First, an Attr whose Value is of type error is formatted as a string, by
-// calling its Error method. Only errors in Attrs receive this special treatment,
-// not errors embedded in structs, slices, maps or other data structures that
-// are processed by the encoding/json package.
-//
-// Second, an encoding failure does not cause Handle to return an error.
-// Instead, the error message is formatted as a string.
-//
-// Each call to Handle results in a single serialized call to io.Writer.Write.
-func (h *JSONHandler) Handle(_ context.Context, r Record) error {
- return h.commonHandler.handle(r)
-}
-
-// Adapted from time.Time.MarshalJSON to avoid allocation.
-func appendJSONTime(s *handleState, t time.Time) {
- if y := t.Year(); y < 0 || y >= 10000 {
- // RFC 3339 is clear that years are 4 digits exactly.
- // See golang.org/issue/4556#c15 for more discussion.
- s.appendError(errors.New("time.Time year outside of range [0,9999]"))
- }
- s.buf.WriteByte('"')
- *s.buf = t.AppendFormat(*s.buf, time.RFC3339Nano)
- s.buf.WriteByte('"')
-}
-
-func appendJSONValue(s *handleState, v Value) error {
- switch v.Kind() {
- case KindString:
- s.appendString(v.str())
- case KindInt64:
- *s.buf = strconv.AppendInt(*s.buf, v.Int64(), 10)
- case KindUint64:
- *s.buf = strconv.AppendUint(*s.buf, v.Uint64(), 10)
- case KindFloat64:
- // json.Marshal is funny about floats; it doesn't
- // always match strconv.AppendFloat. So just call it.
- // That's expensive, but floats are rare.
- if err := appendJSONMarshal(s.buf, v.Float64()); err != nil {
- return err
- }
- case KindBool:
- *s.buf = strconv.AppendBool(*s.buf, v.Bool())
- case KindDuration:
- // Do what json.Marshal does.
- *s.buf = strconv.AppendInt(*s.buf, int64(v.Duration()), 10)
- case KindTime:
- s.appendTime(v.Time())
- case KindAny:
- a := v.Any()
- _, jm := a.(json.Marshaler)
- if err, ok := a.(error); ok && !jm {
- s.appendString(err.Error())
- } else {
- return appendJSONMarshal(s.buf, a)
- }
- default:
- panic(fmt.Sprintf("bad kind: %s", v.Kind()))
- }
- return nil
-}
-
-func appendJSONMarshal(buf *buffer.Buffer, v any) error {
- // Use a json.Encoder to avoid escaping HTML.
- var bb bytes.Buffer
- enc := json.NewEncoder(&bb)
- enc.SetEscapeHTML(false)
- if err := enc.Encode(v); err != nil {
- return err
- }
- bs := bb.Bytes()
- buf.Write(bs[:len(bs)-1]) // remove final newline
- return nil
-}
-
-// appendEscapedJSONString escapes s for JSON and appends it to buf.
-// It does not surround the string in quotation marks.
-//
-// Modified from encoding/json/encode.go:encodeState.string,
-// with escapeHTML set to false.
-func appendEscapedJSONString(buf []byte, s string) []byte {
- char := func(b byte) { buf = append(buf, b) }
- str := func(s string) { buf = append(buf, s...) }
-
- start := 0
- for i := 0; i < len(s); {
- if b := s[i]; b < utf8.RuneSelf {
- if safeSet[b] {
- i++
- continue
- }
- if start < i {
- str(s[start:i])
- }
- char('\\')
- switch b {
- case '\\', '"':
- char(b)
- case '\n':
- char('n')
- case '\r':
- char('r')
- case '\t':
- char('t')
- default:
- // This encodes bytes < 0x20 except for \t, \n and \r.
- str(`u00`)
- char(hex[b>>4])
- char(hex[b&0xF])
- }
- i++
- start = i
- continue
- }
- c, size := utf8.DecodeRuneInString(s[i:])
- if c == utf8.RuneError && size == 1 {
- if start < i {
- str(s[start:i])
- }
- str(`\ufffd`)
- i += size
- start = i
- continue
- }
- // U+2028 is LINE SEPARATOR.
- // U+2029 is PARAGRAPH SEPARATOR.
- // They are both technically valid characters in JSON strings,
- // but don't work in JSONP, which has to be evaluated as JavaScript,
- // and can lead to security holes there. It is valid JSON to
- // escape them, so we do so unconditionally.
- // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
- if c == '\u2028' || c == '\u2029' {
- if start < i {
- str(s[start:i])
- }
- str(`\u202`)
- char(hex[c&0xF])
- i += size
- start = i
- continue
- }
- i += size
- }
- if start < len(s) {
- str(s[start:])
- }
- return buf
-}
-
-var hex = "0123456789abcdef"
-
-// Copied from encoding/json/tables.go.
-//
-// safeSet holds the value true if the ASCII character with the given array
-// position can be represented inside a JSON string without any further
-// escaping.
-//
-// All values are true except for the ASCII control characters (0-31), the
-// double quote ("), and the backslash character ("\").
-var safeSet = [utf8.RuneSelf]bool{
- ' ': true,
- '!': true,
- '"': false,
- '#': true,
- '$': true,
- '%': true,
- '&': true,
- '\'': true,
- '(': true,
- ')': true,
- '*': true,
- '+': true,
- ',': true,
- '-': true,
- '.': true,
- '/': true,
- '0': true,
- '1': true,
- '2': true,
- '3': true,
- '4': true,
- '5': true,
- '6': true,
- '7': true,
- '8': true,
- '9': true,
- ':': true,
- ';': true,
- '<': true,
- '=': true,
- '>': true,
- '?': true,
- '@': true,
- 'A': true,
- 'B': true,
- 'C': true,
- 'D': true,
- 'E': true,
- 'F': true,
- 'G': true,
- 'H': true,
- 'I': true,
- 'J': true,
- 'K': true,
- 'L': true,
- 'M': true,
- 'N': true,
- 'O': true,
- 'P': true,
- 'Q': true,
- 'R': true,
- 'S': true,
- 'T': true,
- 'U': true,
- 'V': true,
- 'W': true,
- 'X': true,
- 'Y': true,
- 'Z': true,
- '[': true,
- '\\': false,
- ']': true,
- '^': true,
- '_': true,
- '`': true,
- 'a': true,
- 'b': true,
- 'c': true,
- 'd': true,
- 'e': true,
- 'f': true,
- 'g': true,
- 'h': true,
- 'i': true,
- 'j': true,
- 'k': true,
- 'l': true,
- 'm': true,
- 'n': true,
- 'o': true,
- 'p': true,
- 'q': true,
- 'r': true,
- 's': true,
- 't': true,
- 'u': true,
- 'v': true,
- 'w': true,
- 'x': true,
- 'y': true,
- 'z': true,
- '{': true,
- '|': true,
- '}': true,
- '~': true,
- '\u007f': true,
-}