summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-errors/v2/runtime.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2023-11-30 16:22:34 +0000
committerLibravatar GitHub <noreply@github.com>2023-11-30 16:22:34 +0000
commiteb170003b81504ba6eb85f950c223dc9eaf1cfca (patch)
treef1f9779e14875faa70f4db85a8cf19100633884d /vendor/codeberg.org/gruf/go-errors/v2/runtime.go
parent[bugfix] always go through status parent dereferencing on isNew, even on data... (diff)
downloadgotosocial-eb170003b81504ba6eb85f950c223dc9eaf1cfca.tar.xz
[bugfix] return 400 Bad Request on more cases of malformed AS data (#2399)
Diffstat (limited to 'vendor/codeberg.org/gruf/go-errors/v2/runtime.go')
-rw-r--r--vendor/codeberg.org/gruf/go-errors/v2/runtime.go97
1 files changed, 97 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-errors/v2/runtime.go b/vendor/codeberg.org/gruf/go-errors/v2/runtime.go
new file mode 100644
index 000000000..0c8cf11cd
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-errors/v2/runtime.go
@@ -0,0 +1,97 @@
+package errors
+
+import (
+ "encoding/json"
+ "runtime"
+ "strconv"
+ "strings"
+ "unsafe"
+)
+
+// Callers ...
+type Callers []runtime.Frame
+
+// MarshalJSON implements json.Marshaler to provide an easy, simple default.
+func (c Callers) MarshalJSON() ([]byte, error) {
+ // JSON-able frame type
+ type jsonFrame struct {
+ Func string `json:"func"`
+ File string `json:"file"`
+ Line int `json:"line"`
+ }
+
+ // Allocate expected size jsonFrame slice
+ jsonFrames := make([]jsonFrame, len(c))
+
+ // Convert each to jsonFrame object
+ for i := 0; i < len(c); i++ {
+ frame := c[i]
+ jsonFrames[i] = jsonFrame{
+ Func: funcName(frame.Func),
+ File: frame.File,
+ Line: frame.Line,
+ }
+ }
+
+ // marshal converted frames
+ return json.Marshal(jsonFrames)
+}
+
+// String will return a simple string representation of receiving Callers slice.
+func (c Callers) String() string {
+ // Guess-timate to reduce allocs
+ buf := make([]byte, 0, 64*len(c))
+
+ for i := 0; i < len(c); i++ {
+ frame := c[i]
+
+ // Append formatted caller info
+ fn := funcName(frame.Func)
+ buf = append(buf, fn+"()\n\t"+frame.File+":"...)
+ buf = strconv.AppendInt(buf, int64(frame.Line), 10)
+ buf = append(buf, '\n')
+ }
+
+ return *(*string)(unsafe.Pointer(&buf))
+}
+
+// funcName formats a function name to a quickly-readable string.
+func funcName(fn *runtime.Func) string {
+ if fn == nil {
+ return ""
+ }
+
+ // Get func name
+ // for formatting.
+ name := fn.Name()
+
+ // Drop all but the package name and function name, no mod path
+ if idx := strings.LastIndex(name, "/"); idx >= 0 {
+ name = name[idx+1:]
+ }
+
+ const params = `[...]`
+
+ // Drop any generic type parameter markers
+ if idx := strings.Index(name, params); idx >= 0 {
+ name = name[:idx] + name[idx+len(params):]
+ }
+
+ return name
+}
+
+// gatherFrames collates runtime frames from a frame iterator.
+func gatherFrames(iter *runtime.Frames, n int) Callers {
+ if iter == nil {
+ return nil
+ }
+ frames := make([]runtime.Frame, 0, n)
+ for {
+ f, ok := iter.Next()
+ if !ok {
+ break
+ }
+ frames = append(frames, f)
+ }
+ return frames
+}