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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

contract.gno

2.50 Kb · 81 lines
 1// Package importdemo shows a realm importing and composing packages from
 2// ANOTHER namespace — the whole point of the demo.
 3//
 4// v2 imported gno.land/p/archive/dom, which is published on no chain we target
 5// (absent on both sapphire and pearl), so it type-checked locally but could
 6// never be deployed: `addpkg` failed with
 7// `could not import gno.land/p/archive/dom (unknown import path)`. v2 is
 8// archived (`ignore = true`); this version rebuilds the same thread-of-posts
 9// idea on foreign packages that are actually on chain — `p/nt/avl/v0` for
10// ordered storage and `p/nt/ufmt/v0` for formatting.
11//
12// Deliberately keeps no realm state: Render builds the thread on each call, so
13// output depends only on the code and the demo is reproducible.
14package importdemo
15
16import (
17	"strconv"
18	"strings"
19
20	"gno.land/p/nt/avl/v0"
21	"gno.land/p/nt/ufmt/v0"
22)
23
24// thread is a titled list of posts, kept in an avl.Tree so iteration is ordered
25// by key rather than by insertion — the same guarantee the realm needs for a
26// stable Render.
27type thread struct {
28	name  string
29	posts *avl.Tree // zero-padded index -> *post
30	n     int
31}
32
33type post struct {
34	title string
35	body  string
36}
37
38func newThread(name string) *thread {
39	return &thread{name: name, posts: avl.NewTree()}
40}
41
42// addPost appends a post. The key is zero-padded so avl's lexicographic order
43// matches insertion order past 9 entries ("10" would otherwise sort before "9").
44func (t *thread) addPost(title, body string) {
45	t.posts.Set(padIdx(t.n), &post{title: title, body: body})
46	t.n++
47}
48
49// padIdx renders i as a fixed-width, zero-padded key.
50//
51// Done by hand on purpose: gno's ufmt supports NO width or padding flags, so
52// ufmt.Sprintf("%03d", 7) yields "7", not "007" — silently, with no error. Keys
53// built that way sort as "0","1","10","11","2", which quietly reorders every
54// thread past nine posts (TestOrderSurvivesPastNinePosts covers exactly this).
55func padIdx(i int) string {
56	s := strconv.Itoa(i)
57	for len(s) < 3 {
58		s = "0" + s
59	}
60	return s
61}
62
63// String renders the thread as Markdown.
64func (t *thread) String() string {
65	var b strings.Builder
66	b.WriteString(ufmt.Sprintf("# [thread] %s\n\n", t.name))
67	t.posts.Iterate("", "", func(_ string, v any) bool {
68		p := v.(*post)
69		b.WriteString(ufmt.Sprintf("## %s\n%s\n", p.title, p.body))
70		return false
71	})
72	return b.String()
73}
74
75// Render renders the demo thread for gnoweb.
76func Render(path string) string {
77	t := newThread("Hello!")
78	t.addPost("Foo", "foo foo foo")
79	t.addPost("Bar", "bar bar bar")
80	return t.String()
81}