Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ujson #1038

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions examples/gno.land/p/demo/ujson/format.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package ujson

// This package strives to have the same behavior as json.Marshal but does not support all types and returns strings

import (
"std"
"strconv"
"strings"

"gno.land/p/demo/avl"
)

type JSONAble interface {
ToJSON() string
}

type FormatKV struct {
Key string
Value interface{}
Raw bool
}

// does not work for slices, use FormatSlice instead
func FormatAny(p interface{}) string {
switch p.(type) {
case std.Address:
return FormatString(string(p.(std.Address)))
case *avl.Tree:
return FormatAVLTree(p.(*avl.Tree))
case avl.Tree:
return FormatAVLTree(&p.(avl.Tree))
case JSONAble:
return p.(JSONAble).ToJSON()
case string:
return FormatString(p.(string))
case uint64:
return FormatUint64(p.(uint64))
case uint32:
return FormatUint64(uint64(p.(uint32)))
case uint:
return FormatUint64(uint64(p.(uint)))
case int64:
return FormatInt64(p.(int64))
case int32:
return FormatInt64(int64(p.(int32)))
case int:
return FormatInt64(int64(p.(int)))
case float32:
panic("float32 not implemented")
case float64:
panic("float64 not implemented")
case bool:
return FormatBool(p.(bool))
default:
return "null"
}
}

func FormatUint64(i uint64) string {
return strconv.FormatUint(i, 10)
}

func FormatInt64(i int64) string {
return strconv.FormatInt(i, 10)
}

func FormatSlice(s []interface{}) string {
elems := make([]string, len(s))
for i, elem := range s {
elems[i] = FormatAny(elem)
}
return "[" + strings.Join(elems, ",") + "]"
}

func FormatObject(kv []FormatKV) string {
elems := make([]string, len(kv))
i := 0
for _, elem := range kv {
var val string
if elem.Raw {
val = elem.Value.(string)
} else {
val = FormatAny(elem.Value)
}
elems[i] = FormatString(elem.Key) + ":" + val
i++
}
return "{" + strings.Join(elems, ",") + "}"
}

func FormatBool(b bool) string {
if b {
return "true"
}
return "false"
}

func FormatAVLTree(t *avl.Tree) string {
if t == nil {
return "{}"
}
kv := make([]FormatKV, 0, t.Size())
t.Iterate("", "", func(key string, value interface{}) bool {
kv = append(kv, FormatKV{key, value, false})
return false
})
return FormatObject(kv)
}
5 changes: 5 additions & 0 deletions examples/gno.land/p/demo/ujson/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module gno.land/p/demo/ujson

require (
"gno.land/p/demo/avl" v0.0.0-latest
)
Loading
Loading