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}