string.go

 1package graphql
 2
 3import (
 4	"fmt"
 5	"io"
 6	"strconv"
 7)
 8
 9const encodeHex = "0123456789ABCDEF"
10
11func MarshalString(s string) Marshaler {
12	return WriterFunc(func(w io.Writer) {
13		writeQuotedString(w, s)
14	})
15}
16
17func writeQuotedString(w io.Writer, s string) {
18	start := 0
19	io.WriteString(w, `"`)
20
21	for i, c := range s {
22		if c < 0x20 || c == '\\' || c == '"' {
23			io.WriteString(w, s[start:i])
24
25			switch c {
26			case '\t':
27				io.WriteString(w, `\t`)
28			case '\r':
29				io.WriteString(w, `\r`)
30			case '\n':
31				io.WriteString(w, `\n`)
32			case '\\':
33				io.WriteString(w, `\\`)
34			case '"':
35				io.WriteString(w, `\"`)
36			default:
37				io.WriteString(w, `\u00`)
38				w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]})
39			}
40
41			start = i + 1
42		}
43	}
44
45	io.WriteString(w, s[start:])
46	io.WriteString(w, `"`)
47}
48
49func UnmarshalString(v interface{}) (string, error) {
50	switch v := v.(type) {
51	case string:
52		return v, nil
53	case int:
54		return strconv.Itoa(v), nil
55	case float64:
56		return fmt.Sprintf("%f", v), nil
57	case bool:
58		if v {
59			return "true", nil
60		} else {
61			return "false", nil
62		}
63	case nil:
64		return "null", nil
65	default:
66		return "", fmt.Errorf("%T is not a string", v)
67	}
68}