1 // In this file, JSON refers to WTF-JSON, a variant of JSON used by Minetest
2 // where \u00XX escapes in string literals act like Go's \xXX escapes.
25 func (s Stack) String() string {
33 } else if s.Wear > 0 {
35 } else if s.Count > 1 {
39 return strings.Join([]string{
43 optJSONStr(string(s.ItemMeta)),
47 func optJSONStr(s string) string {
49 if r <= ' ' || r == '"' || r >= utf8.RuneSelf {
56 func jsonStr(s string) string {
68 b := new(strings.Builder)
71 for i := 0; i < len(s); i++ {
74 fmt.Fprintf(b, "\\%c", esc[c])
75 case ' ' <= c && c <= '~':
78 fmt.Fprintf(b, "\\u%04x", c)
86 func (stk *Stack) Scan(state fmt.ScanState, verb rune) (err error) {
95 nm, err := scanOptJSONStr(state)
102 if _, err := fmt.Fscan(state, &stk.Count, &stk.Wear); err != nil {
106 s, err := scanOptJSONStr(state)
110 stk.ItemMeta = ItemMeta(s)
115 func scanOptJSONStr(state fmt.ScanState) (string, error) {
118 r, _, err := state.ReadRune()
125 return scanJSONStr(state)
128 token, err := state.Token(false, func(r rune) bool {
129 return r != ' ' && r != '\n'
131 return string(token), err
134 func scanJSONStr(state fmt.ScanState) (s string, rerr error) {
135 r, _, err := state.ReadRune()
140 return "", fmt.Errorf("unexpected rune: %q", r)
145 rerr = io.ErrUnexpectedEOF
149 b := new(strings.Builder)
151 r, _, err := state.ReadRune()
153 return b.String(), err
158 return b.String(), nil
160 r, _, err := state.ReadRune()
162 return b.String(), err
181 r, _, err := state.ReadRune()
183 return b.String(), err
187 n, err := strconv.ParseUint(string(hex[:]), 16, 8)
189 return b.String(), err
193 return b.String(), fmt.Errorf("invalid escape: \\%c", r)