spew.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Copyright (c) 2013 Dave Collins <dave@davec.name>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. package spew
  17. import (
  18. "fmt"
  19. "io"
  20. "os"
  21. )
  22. // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
  23. // passed with a default Formatter interface returned by NewFormatter. It
  24. // returns the formatted string as a value that satisfies error. See
  25. // NewFormatter for formatting details.
  26. //
  27. // This function is shorthand for the following syntax:
  28. //
  29. // fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
  30. func Errorf(format string, a ...interface{}) (err error) {
  31. return fmt.Errorf(format, convertArgs(a)...)
  32. }
  33. // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
  34. // passed with a default Formatter interface returned by NewFormatter. It
  35. // returns the number of bytes written and any write error encountered. See
  36. // NewFormatter for formatting details.
  37. //
  38. // This function is shorthand for the following syntax:
  39. //
  40. // fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
  41. func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
  42. return fmt.Fprint(w, convertArgs(a)...)
  43. }
  44. // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
  45. // passed with a default Formatter interface returned by NewFormatter. It
  46. // returns the number of bytes written and any write error encountered. See
  47. // NewFormatter for formatting details.
  48. //
  49. // This function is shorthand for the following syntax:
  50. //
  51. // fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
  52. func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
  53. return fmt.Fprintf(w, format, convertArgs(a)...)
  54. }
  55. // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
  56. // passed with a default Formatter interface returned by NewFormatter. See
  57. // NewFormatter for formatting details.
  58. //
  59. // This function is shorthand for the following syntax:
  60. //
  61. // fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
  62. func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
  63. return fmt.Fprintln(w, convertArgs(a)...)
  64. }
  65. // Print is a wrapper for fmt.Print that treats each argument as if it were
  66. // passed with a default Formatter interface returned by NewFormatter. It
  67. // returns the number of bytes written and any write error encountered. See
  68. // NewFormatter for formatting details.
  69. //
  70. // This function is shorthand for the following syntax:
  71. //
  72. // fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
  73. func Print(a ...interface{}) (n int, err error) {
  74. return fmt.Print(convertArgs(a)...)
  75. }
  76. // Printf is a wrapper for fmt.Printf that treats each argument as if it were
  77. // passed with a default Formatter interface returned by NewFormatter. It
  78. // returns the number of bytes written and any write error encountered. See
  79. // NewFormatter for formatting details.
  80. //
  81. // This function is shorthand for the following syntax:
  82. //
  83. // fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
  84. func Printf(format string, a ...interface{}) (n int, err error) {
  85. return fmt.Printf(format, convertArgs(a)...)
  86. }
  87. // Println is a wrapper for fmt.Println that treats each argument as if it were
  88. // passed with a default Formatter interface returned by NewFormatter. It
  89. // returns the number of bytes written and any write error encountered. See
  90. // NewFormatter for formatting details.
  91. //
  92. // This function is shorthand for the following syntax:
  93. //
  94. // fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
  95. func Println(a ...interface{}) (n int, err error) {
  96. return fmt.Println(convertArgs(a)...)
  97. }
  98. // convertArgs accepts a slice of arguments and returns a slice of the same
  99. // length with each argument converted to a default spew Formatter interface.
  100. func convertArgs(args []interface{}) (formatters []interface{}) {
  101. formatters = make([]interface{}, len(args))
  102. for index, arg := range args {
  103. formatters[index] = NewFormatter(arg)
  104. }
  105. return formatters
  106. }
  107. // SpewState provides a context which can have its own configuration options.
  108. // The configuration options can be manipulated via the Config method. The
  109. // methods of SpewState are equivalent to the top-level functions.
  110. //
  111. // A SpewState does not need any special initialization, so new(SpewState) or
  112. // just declaring a SpewState variable, is sufficient to initialilize a
  113. // SpewState using the default configuration options.
  114. type SpewState struct {
  115. cs *ConfigState
  116. }
  117. // Config returns a pointer to the active ConfigState for the SpewState
  118. // instance. Set the fields of the returned structure to the desired
  119. // configuration settings for the instance.
  120. func (s *SpewState) Config() (cs *ConfigState) {
  121. if s.cs == nil {
  122. cs := defaultConfig
  123. s.cs = &cs
  124. }
  125. return s.cs
  126. }
  127. // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
  128. // passed with a Formatter interface returned by s.NewFormatter. It returns
  129. // the formatted string as a value that satisfies error. See NewFormatter
  130. // for formatting details.
  131. //
  132. // This function is shorthand for the following syntax:
  133. //
  134. // fmt.Errorf(format, s.NewFormatter(a), s.NewFormatter(b))
  135. func (s *SpewState) Errorf(format string, a ...interface{}) (err error) {
  136. return fmt.Errorf(format, s.convertArgs(a)...)
  137. }
  138. // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
  139. // passed with a Formatter interface returned by s.NewFormatter. It returns
  140. // the number of bytes written and any write error encountered. See
  141. // NewFormatter for formatting details.
  142. //
  143. // This function is shorthand for the following syntax:
  144. //
  145. // fmt.Fprint(w, s.NewFormatter(a), s.NewFormatter(b))
  146. func (s *SpewState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
  147. return fmt.Fprint(w, s.convertArgs(a)...)
  148. }
  149. // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
  150. // passed with a Formatter interface returned by s.NewFormatter. It returns
  151. // the number of bytes written and any write error encountered. See
  152. // NewFormatter for formatting details.
  153. //
  154. // This function is shorthand for the following syntax:
  155. //
  156. // fmt.Fprintf(w, format, s.NewFormatter(a), s.NewFormatter(b))
  157. func (s *SpewState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
  158. return fmt.Fprintf(w, format, s.convertArgs(a)...)
  159. }
  160. // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
  161. // passed with a Formatter interface returned by s.NewFormatter. See
  162. // NewFormatter for formatting details.
  163. //
  164. // This function is shorthand for the following syntax:
  165. //
  166. // fmt.Fprintln(w, s.NewFormatter(a), s.NewFormatter(b))
  167. func (s *SpewState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
  168. return fmt.Fprintln(w, s.convertArgs(a)...)
  169. }
  170. // Print is a wrapper for fmt.Print that treats each argument as if it were
  171. // passed with a Formatter interface returned by s.NewFormatter. It returns
  172. // the number of bytes written and any write error encountered. See
  173. // NewFormatter for formatting details.
  174. //
  175. // This function is shorthand for the following syntax:
  176. //
  177. // fmt.Print(s.NewFormatter(a), s.NewFormatter(b))
  178. func (s *SpewState) Print(a ...interface{}) (n int, err error) {
  179. return fmt.Print(s.convertArgs(a)...)
  180. }
  181. // Printf is a wrapper for fmt.Printf that treats each argument as if it were
  182. // passed with a Formatter interface returned by s.NewFormatter. It returns
  183. // the number of bytes written and any write error encountered. See
  184. // NewFormatter for formatting details.
  185. //
  186. // This function is shorthand for the following syntax:
  187. //
  188. // fmt.Printf(format, s.NewFormatter(a), s.NewFormatter(b))
  189. func (s *SpewState) Printf(format string, a ...interface{}) (n int, err error) {
  190. return fmt.Printf(format, s.convertArgs(a)...)
  191. }
  192. // Println is a wrapper for fmt.Println that treats each argument as if it were
  193. // passed with a Formatter interface returned by s.NewFormatter. It returns
  194. // the number of bytes written and any write error encountered. See
  195. // NewFormatter for formatting details.
  196. //
  197. // This function is shorthand for the following syntax:
  198. //
  199. // fmt.Println(s.NewFormatter(a), s.NewFormatter(b))
  200. func (s *SpewState) Println(a ...interface{}) (n int, err error) {
  201. return fmt.Println(s.convertArgs(a)...)
  202. }
  203. /*
  204. NewFormatter returns a custom formatter that satisfies the fmt.Formatter
  205. interface. As a result, it integrates cleanly with standard fmt package
  206. printing functions. The formatter is useful for inline printing of smaller data
  207. types similar to the standard %v format specifier.
  208. The custom formatter only responds to the %v and %+v verb combinations. Any
  209. other variations such as %x, %q, and %#v will be sent to the the standard fmt
  210. package for formatting. In addition, the custom formatter ignores the width and
  211. precision arguments (however they will still work on the format specifiers not
  212. handled by the custom formatter).
  213. Typically this function shouldn't be called directly. It is much easier to make
  214. use of the custom formatter by calling one of the convenience functions such as
  215. s.Printf, s.Println, or s.Printf.
  216. */
  217. func (s *SpewState) NewFormatter(v interface{}) fmt.Formatter {
  218. // The Config method creates the config state if needed, so call it instead
  219. // of using s.cs directly to ensure the zero value SpewState is sane.
  220. return newFormatter(s.Config(), v)
  221. }
  222. // Fdump formats and displays the passed arguments to io.Writer w. It formats
  223. // exactly the same as Dump.
  224. func (s *SpewState) Fdump(w io.Writer, a ...interface{}) {
  225. // The Config method creates the config state if needed, so call it instead
  226. // of using s.cs directly to ensure the zero value SpewState is sane.
  227. fdump(s.Config(), w, a...)
  228. }
  229. /*
  230. Dump displays the passed parameters to standard out with newlines, customizable
  231. indentation, and additional debug information such as complete types and all
  232. pointer addresses used to indirect to the final value. It provides the
  233. following features over the built-in printing facilities provided by the fmt
  234. package:
  235. * Pointers are dereferenced and followed
  236. * Circular data structures are detected and handled properly
  237. * Custom error/Stringer interfaces are optionally invoked, including
  238. on unexported types
  239. * Custom types which only implement the error/Stringer interfaces via
  240. a pointer receiver are optionally invoked when passing non-pointer
  241. variables
  242. The configuration options are controlled by accessing the ConfigState associated
  243. with s via the Config method. See ConfigState for options documentation.
  244. See Fdump if you would prefer dump to an arbitrary io.Writer.
  245. */
  246. func (s *SpewState) Dump(a ...interface{}) {
  247. // The Config method creates the config state if needed, so call it instead
  248. // of using s.cs directly to ensure the zero value SpewState is sane.
  249. fdump(s.Config(), os.Stdout, a...)
  250. }
  251. // convertArgs accepts a slice of arguments and returns a slice of the same
  252. // length with each argument converted to a spew Formatter interface using
  253. // the ConfigState associated with s.
  254. func (s *SpewState) convertArgs(args []interface{}) (formatters []interface{}) {
  255. // The Config method creates the config state if needed, so call it instead
  256. // of using s.cs directly to ensure the zero value SpewState is sane.
  257. cs := s.Config()
  258. formatters = make([]interface{}, len(args))
  259. for index, arg := range args {
  260. formatters[index] = newFormatter(cs, arg)
  261. }
  262. return formatters
  263. }