outfmt.gno
2.14 Kb · 121 lines
1package outfmt
2
3import (
4 "math/rand"
5 "strconv"
6 "strings"
7
8 "gno.land/p/nt/ufmt/v0"
9)
10
11type Result struct {
12 Number int
13 Text string
14 Numbers []int
15}
16
17func (res *Result) String() string {
18 output := ufmt.Sprintf("Text: %s\n", res.Text)
19 output += ufmt.Sprintf("Number: %d\n", res.Number)
20
21 output += "Numbers:"
22 for _, number := range res.Numbers {
23 output += ufmt.Sprintf(" %d", number)
24 }
25 output += "\n"
26
27 return output
28}
29
30var rSeed = rand.NewPCG(0, 0)
31
32func genResult() Result {
33 r := rand.New(rSeed)
34
35 // init rand
36 res := Result{
37 Text: "Hello Gnomes!",
38 Number: r.IntN(1000),
39 }
40
41 length := r.IntN(8) + 2
42 res.Numbers = make([]int, length)
43 for i := 0; i < length; i++ {
44 res.Numbers[i] = r.IntN(100)
45 }
46
47 return res
48}
49
50// marshal function to manually convert struct to JSON string
51func (r Result) marshal() string {
52 // Start JSON string
53 jsonStr := `{"Number":` + strconv.Itoa(r.Number) + `,"Text":"` + r.Text + `","Numbers":[`
54
55 for i, num := range r.Numbers {
56 jsonStr += strconv.Itoa(num)
57 if i < len(r.Numbers)-1 {
58 jsonStr += ","
59 }
60 }
61
62 jsonStr += "]}"
63
64 return jsonStr
65}
66
67func Render(path string) string {
68 if path == "" {
69 output := ""
70 output += "* [?fmt=stringer](/r/moul/outfmt:?fmt=stringer)\n"
71 output += "* [?fmt=json](/r/moul/outfmt:?fmt=json)\n"
72 output += "* [?fmt=jsonp](/r/moul/outfmt:?fmt=jsonp)\n"
73 return output
74 }
75
76 // parsing
77 fmt := "stringer" // default
78 // FIXME: whitelist and use net/url.
79 {
80 parts := strings.Split(path, "?")
81 if len(parts) == 2 {
82 // path := parts[0]
83 query := parts[1]
84 if query != "" {
85 parts = strings.Split(query, "=")
86 if len(parts) == 2 {
87 k := parts[0]
88 v := parts[1]
89 if k == "fmt" {
90 fmt = v
91 }
92 }
93 }
94 }
95 }
96
97 // rendering
98
99 res := genResult()
100 switch fmt {
101 case "stringer":
102 return res.String()
103 case "json":
104 // FIXME: return content-type?
105 out := res.marshal()
106 return string(out)
107 case "jsonp":
108 // FIXME: return content-type?
109 callback := "callback" // FIXME: get it from query
110 out := res.marshal()
111 return callback + "(" + string(out) + ")"
112 default:
113 panic("unknown format")
114 }
115}
116
117func checkErr(err error) {
118 if err != nil {
119 panic(err)
120 }
121}