github.com/mitranim/gg@v0.1.17/grepr/grepr.go (about) 1 /* 2 Missing feature of the standard library: printing arbitrary inputs as Go code, 3 with proper spacing and support for multi-line output with indentation. The 4 name "repr" stands for "representation" and alludes to the Python function with 5 the same name. 6 */ 7 package grepr 8 9 import ( 10 "fmt" 11 r "reflect" 12 u "unsafe" 13 14 "github.com/mitranim/gg" 15 ) 16 17 // Default config used by top-level formatting functions in this package. 18 var ConfDefault = Conf{Indent: gg.Indent} 19 20 // Config that allows formatting of struct zero fields. 21 var ConfFull = Conf{Indent: gg.Indent, ZeroFields: true} 22 23 /* 24 Formatting config. 25 26 * `.Indent` controls indentation. If empty, output is single line. 27 * `.ZeroFields`, if set, forces printing of zero fields in structs. 28 By default zero fields are skipped. 29 * `.Pkg`, if set, indicates the package name to strip from type names. 30 */ 31 type Conf struct { 32 Indent string 33 ZeroFields bool 34 Pkg string 35 } 36 37 /* 38 Short for "is single line". If `.Indent` is empty, this is true, and output 39 is single-line. Otherwise output is multi-line. 40 */ 41 func (self Conf) IsSingle() bool { return self.Indent == `` } 42 43 // Short for "is multi line". Inverse of `.IsSingle`. 44 func (self Conf) IsMulti() bool { return self.Indent != `` } 45 46 // Inverse of `.ZeroFields`. 47 func (self Conf) SkipZeroFields() bool { return !self.ZeroFields } 48 49 // Shortcut for creating a pretty-formatter with this config. 50 func (self Conf) Fmt() Fmt { 51 var buf Fmt 52 buf.Conf = self 53 return buf 54 } 55 56 // Short for "formatter". 57 type Fmt struct { 58 Conf 59 gg.Buf 60 Lvl int 61 ElideType bool 62 Visited gg.Set[u.Pointer] 63 } 64 65 /* 66 Similar to `fmt.Sprintf("%#v")` or `gg.GoString`, but more advanced. 67 Formats the input as Go code, using the config `ConfDefault`, returning 68 the resulting string. 69 */ 70 func String[A any](src A) string { return StringIndent(src, 0) } 71 72 /* 73 Similar to `fmt.Sprintf("%#v")` or `gg.GoString`, but more advanced. 74 Formats the input as Go code, using the config `ConfDefault`, returning 75 the resulting bytes. 76 */ 77 func Bytes[A any](src A) []byte { return BytesIndent(src, 0) } 78 79 /* 80 Formats the input as Go code, using the given config, returning the 81 resulting string. 82 */ 83 func StringC[A any](conf Conf, src A) string { return StringIndentC(conf, src, 0) } 84 85 /* 86 Formats the input as Go code, using the given config, returning the 87 resulting bytes. 88 */ 89 func BytesC[A any](conf Conf, src A) []byte { return BytesIndentC(conf, src, 0) } 90 91 /* 92 Formats the input as Go code, using the default config with the given 93 indentation level, returning the resulting string. 94 */ 95 func StringIndent[A any](src A, lvl int) string { 96 return StringIndentC(ConfDefault, src, lvl) 97 } 98 99 /* 100 Formats the input as Go code, using the default config with the given 101 indentation level, returning the resulting bytes. 102 */ 103 func BytesIndent[A any](src A, lvl int) []byte { 104 return BytesIndentC(ConfDefault, src, lvl) 105 } 106 107 /* 108 Formats the input as Go code, using the given config with the given indentation 109 level, returning the resulting string. 110 */ 111 func StringIndentC[A any](conf Conf, src A, lvl int) string { 112 return gg.ToString(BytesIndentC(conf, src, lvl)) 113 } 114 115 /* 116 Formats the input as Go code, using the given config with the given indentation 117 level, returning the resulting bytes. 118 */ 119 func BytesIndentC[A any](conf Conf, src A, lvl int) []byte { 120 buf := conf.Fmt() 121 buf.Lvl += lvl 122 buf.fmtAny(gg.Type[A](), r.ValueOf(gg.AnyNoEscUnsafe(src))) 123 return buf.Buf 124 } 125 126 /* 127 Shortcut for printing the input as Go code, prefixed with the given description, 128 using the default config. Handy for debug-printing. 129 */ 130 func Prn[A any](desc string, src A) { fmt.Println(desc, String(src)) } 131 132 // Shortcut for printing the input as Go code, using the default config. 133 func Println[A any](src A) { fmt.Println(String(src)) } 134 135 // Shortcut for printing the input as Go code, using the given config. 136 func PrintlnC[A any](conf Conf, src A) { fmt.Println(StringC(conf, src)) }