Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

debug.gno

2.90 Kb · 93 lines
 1// Package debug provides utilities for logging and displaying debug information
 2// within Gno realms. It supports conditional rendering of logs and metadata,
 3// toggleable via query parameters.
 4//
 5// Key Features:
 6// - Log collection and display using Markdown formatting.
 7// - Metadata display for realm path, address, and height.
 8// - Collapsible debug section for cleaner presentation.
 9// - Query-based debug toggle using `?debug=1`.
10package debug
11
12import (
13	"chain/runtime"
14	"chain/runtime/unsafe"
15	"time"
16
17	"gno.land/p/moul/md/v0"
18	"gno.land/p/moul/mdtable/v0"
19	"gno.land/p/moul/realmpath/v0"
20	"gno.land/p/nt/ufmt/v0"
21)
22
23// Debug encapsulates debug information, including logs and metadata.
24type Debug struct {
25	Logs         []string
26	HideMetadata bool
27}
28
29// Log appends a new line of debug information to the Logs slice.
30func (d *Debug) Log(line string) {
31	d.Logs = append(d.Logs, line)
32}
33
34// Render generates the debug content as a collapsible Markdown section.
35// It conditionally renders logs and metadata if enabled via the `?debug=1` query parameter.
36func (d Debug) Render(path string) string {
37	if realmpath.Parse(path).Query.Get("debug") != "1" {
38		return ""
39	}
40
41	var content string
42
43	if d.Logs != nil {
44		content += md.H3("Logs")
45		content += md.BulletList(d.Logs)
46	}
47
48	if !d.HideMetadata {
49		content += md.H3("Metadata")
50		table := mdtable.Table{
51			Headers: []string{"Key", "Value"},
52		}
53		table.Append([]string{"`std.CurrentRealm().PkgPath()`", string(unsafe.CurrentRealm().PkgPath())})
54		table.Append([]string{"`std.CurrentRealm().Address()`", string(unsafe.CurrentRealm().Address())})
55		table.Append([]string{"`std.PreviousRealm().PkgPath()`", string(unsafe.PreviousRealm().PkgPath())})
56		table.Append([]string{"`std.PreviousRealm().Address()`", string(unsafe.PreviousRealm().Address())})
57		table.Append([]string{"`std.ChainHeight()`", ufmt.Sprintf("%d", runtime.ChainHeight())})
58		table.Append([]string{"`time.Now().Format(time.RFC3339)`", time.Now().Format(time.RFC3339)})
59		content += table.String()
60	}
61
62	if content == "" {
63		return ""
64	}
65
66	return md.CollapsibleSection("debug", content)
67}
68
69// Render displays metadata about the current realm but does not display logs.
70// This function uses a default Debug struct with metadata enabled and no logs.
71func Render(path string) string {
72	return Debug{}.Render(path)
73}
74
75// IsEnabled checks if the `?debug=1` query parameter is set in the given path.
76// Returns true if debugging is enabled, otherwise false.
77func IsEnabled(path string) bool {
78	req := realmpath.Parse(path)
79	return req.Query.Get("debug") == "1"
80}
81
82// ToggleURL modifies the given path's query string to toggle the `?debug=1` parameter.
83// If debugging is currently enabled, it removes the parameter.
84// If debugging is disabled, it adds the parameter.
85func ToggleURL(path string) string {
86	req := realmpath.Parse(path)
87	if IsEnabled(path) {
88		req.Query.Del("debug")
89	} else {
90		req.Query.Add("debug", "1")
91	}
92	return req.String()
93}