json.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Package json minifies JSON following the specifications at http://json.org/.
  2. package json // import "github.com/tdewolff/minify/json"
  3. import (
  4. "io"
  5. "github.com/tdewolff/minify"
  6. "github.com/tdewolff/parse/json"
  7. )
  8. var (
  9. commaBytes = []byte(",")
  10. colonBytes = []byte(":")
  11. )
  12. ////////////////////////////////////////////////////////////////
  13. // DefaultMinifier is the default minifier.
  14. var DefaultMinifier = &Minifier{}
  15. // Minifier is a JSON minifier.
  16. type Minifier struct{}
  17. // Minify minifies JSON data, it reads from r and writes to w.
  18. func Minify(m *minify.M, w io.Writer, r io.Reader, params map[string]string) error {
  19. return DefaultMinifier.Minify(m, w, r, params)
  20. }
  21. // Minify minifies JSON data, it reads from r and writes to w.
  22. func (o *Minifier) Minify(_ *minify.M, w io.Writer, r io.Reader, _ map[string]string) error {
  23. skipComma := true
  24. p := json.NewParser(r)
  25. defer p.Restore()
  26. for {
  27. state := p.State()
  28. gt, text := p.Next()
  29. if gt == json.ErrorGrammar {
  30. if p.Err() != io.EOF {
  31. return p.Err()
  32. }
  33. return nil
  34. }
  35. if !skipComma && gt != json.EndObjectGrammar && gt != json.EndArrayGrammar {
  36. if state == json.ObjectKeyState || state == json.ArrayState {
  37. if _, err := w.Write(commaBytes); err != nil {
  38. return err
  39. }
  40. } else if state == json.ObjectValueState {
  41. if _, err := w.Write(colonBytes); err != nil {
  42. return err
  43. }
  44. }
  45. }
  46. skipComma = gt == json.StartObjectGrammar || gt == json.StartArrayGrammar
  47. if _, err := w.Write(text); err != nil {
  48. return err
  49. }
  50. }
  51. }