1 // In this file, JSON refers to WTF-JSON.
3 // BUG(mt): Stackstrings use variant of JSON called WTF-JSON
4 // where \u00XX escapes in string literals act like Go's \xXX escapes.
5 // This should not be fixed because it would break existing items.
28 // String returns the Stack's stackstring.
29 func (s Stack) String() string {
37 } else if s.Wear > 0 {
39 } else if s.Count > 1 {
43 return strings.Join([]string{
47 optJSONStr(string(s.ItemMeta)),
51 func optJSONStr(s string) string {
53 if r <= ' ' || r == '"' || r >= utf8.RuneSelf {
60 func jsonStr(s string) string {
72 b := new(strings.Builder)
75 for i := 0; i < len(s); i++ {
78 fmt.Fprintf(b, "\\%c", esc[c])
79 case ' ' <= c && c <= '~':
82 fmt.Fprintf(b, "\\u%04x", c)
90 // Scan scans a stackstring, implementing the fmt.Scanner interface.
91 func (stk *Stack) Scan(state fmt.ScanState, verb rune) (err error) {
100 nm, err := scanOptJSONStr(state)
107 if _, err := fmt.Fscan(state, &stk.Count, &stk.Wear); err != nil {
111 s, err := scanOptJSONStr(state)
115 stk.ItemMeta = ItemMeta(s)
120 func scanOptJSONStr(state fmt.ScanState) (string, error) {
123 r, _, err := state.ReadRune()
130 return scanJSONStr(state)
133 token, err := state.Token(false, func(r rune) bool {
134 return r != ' ' && r != '\n'
136 return string(token), err
139 func scanJSONStr(state fmt.ScanState) (s string, rerr error) {
140 r, _, err := state.ReadRune()
145 return "", fmt.Errorf("unexpected rune: %q", r)
150 rerr = io.ErrUnexpectedEOF
154 b := new(strings.Builder)
156 r, _, err := state.ReadRune()
158 return b.String(), err
163 return b.String(), nil
165 r, _, err := state.ReadRune()
167 return b.String(), err
186 r, _, err := state.ReadRune()
188 return b.String(), err
192 n, err := strconv.ParseUint(string(hex[:]), 16, 8)
194 return b.String(), err
198 return b.String(), fmt.Errorf("invalid escape: \\%c", r)