debug.gno
2.84 Kb ยท 92 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 "std"
14 "time"
15
16 "gno.land/p/demo/ufmt"
17 "gno.land/p/moul/md"
18 "gno.land/p/moul/mdtable"
19 "gno.land/p/moul/realmpath"
20)
21
22// Debug encapsulates debug information, including logs and metadata.
23type Debug struct {
24 Logs []string
25 HideMetadata bool
26}
27
28// Log appends a new line of debug information to the Logs slice.
29func (d *Debug) Log(line string) {
30 d.Logs = append(d.Logs, line)
31}
32
33// Render generates the debug content as a collapsible Markdown section.
34// It conditionally renders logs and metadata if enabled via the `?debug=1` query parameter.
35func (d Debug) Render(path string) string {
36 if realmpath.Parse(path).Query.Get("debug") != "1" {
37 return ""
38 }
39
40 var content string
41
42 if d.Logs != nil {
43 content += md.H3("Logs")
44 content += md.BulletList(d.Logs)
45 }
46
47 if !d.HideMetadata {
48 content += md.H3("Metadata")
49 table := mdtable.Table{
50 Headers: []string{"Key", "Value"},
51 }
52 table.Append([]string{"`std.CurrentRealm().PkgPath()`", string(std.CurrentRealm().PkgPath())})
53 table.Append([]string{"`std.CurrentRealm().Address()`", string(std.CurrentRealm().Address())})
54 table.Append([]string{"`std.PreviousRealm().PkgPath()`", string(std.PreviousRealm().PkgPath())})
55 table.Append([]string{"`std.PreviousRealm().Address()`", string(std.PreviousRealm().Address())})
56 table.Append([]string{"`std.ChainHeight()`", ufmt.Sprintf("%d", std.ChainHeight())})
57 table.Append([]string{"`time.Now().Format(time.RFC3339)`", time.Now().Format(time.RFC3339)})
58 content += table.String()
59 }
60
61 if content == "" {
62 return ""
63 }
64
65 return md.CollapsibleSection("debug", content)
66}
67
68// Render displays metadata about the current realm but does not display logs.
69// This function uses a default Debug struct with metadata enabled and no logs.
70func Render(path string) string {
71 return Debug{}.Render(path)
72}
73
74// IsEnabled checks if the `?debug=1` query parameter is set in the given path.
75// Returns true if debugging is enabled, otherwise false.
76func IsEnabled(path string) bool {
77 req := realmpath.Parse(path)
78 return req.Query.Get("debug") == "1"
79}
80
81// ToggleURL modifies the given path's query string to toggle the `?debug=1` parameter.
82// If debugging is currently enabled, it removes the parameter.
83// If debugging is disabled, it adds the parameter.
84func ToggleURL(path string) string {
85 req := realmpath.Parse(path)
86 if IsEnabled(path) {
87 req.Query.Del("debug")
88 } else {
89 req.Query.Add("debug", "1")
90 }
91 return req.String()
92}