wrap.go raw

   1  package text
   2  
   3  // AppendBytesClosure is a function type for appending data from a source to a destination and
   4  // returning the appended-to slice.
   5  type AppendBytesClosure func(dst, src []byte) []byte
   6  
   7  // AppendClosure is a simple append where the caller appends to the destination and returns the
   8  // appended-to slice.
   9  type AppendClosure func(dst []byte) []byte
  10  
  11  // Unquote removes the quotes around a slice of bytes.
  12  func Unquote(b []byte) []byte { return b[1 : len(b)-1] }
  13  
  14  // Noop simply appends the source to the destination slice and returns it.
  15  func Noop(dst, src []byte) []byte { return append(dst, src...) }
  16  
  17  // AppendQuote appends a source of bytes, that have been processed by an AppendBytesClosure and
  18  // returns the appended-to slice.
  19  func AppendQuote(dst, src []byte, ac AppendBytesClosure) []byte {
  20  	dst = append(dst, '"')
  21  	dst = ac(dst, src)
  22  	dst = append(dst, '"')
  23  	return dst
  24  }
  25  
  26  // Quote simply quotes a provided source and attaches it to the provided destination slice.
  27  func Quote(dst, src []byte) []byte { return AppendQuote(dst, src, Noop) }
  28  
  29  // AppendSingleQuote appends a provided AppendBytesClosure's output from a given source of
  30  // bytes, wrapped in single quotes ”.
  31  func AppendSingleQuote(dst, src []byte, ac AppendBytesClosure) []byte {
  32  	dst = append(dst, '\'')
  33  	dst = ac(dst, src)
  34  	dst = append(dst, '\'')
  35  	return dst
  36  }
  37  
  38  // AppendBackticks appends a provided AppendBytesClosure's output from a given source of
  39  // bytes, wrapped in backticks “.
  40  func AppendBackticks(dst, src []byte, ac AppendBytesClosure) []byte {
  41  	dst = append(dst, '`')
  42  	dst = ac(dst, src)
  43  	dst = append(dst, '`')
  44  	return dst
  45  }
  46  
  47  // AppendBrace appends a provided AppendBytesClosure's output from a given source of
  48  // bytes, wrapped in braces ().
  49  func AppendBrace(dst, src []byte, ac AppendBytesClosure) []byte {
  50  	dst = append(dst, '(')
  51  	dst = ac(dst, src)
  52  	dst = append(dst, ')')
  53  	return dst
  54  }
  55  
  56  // AppendParenthesis appends a provided AppendBytesClosure's output from a given source of
  57  // bytes, wrapped in parentheses {}.
  58  func AppendParenthesis(dst, src []byte, ac AppendBytesClosure) []byte {
  59  	dst = append(dst, '{')
  60  	dst = ac(dst, src)
  61  	dst = append(dst, '}')
  62  	return dst
  63  }
  64  
  65  // AppendBracket appends a provided AppendBytesClosure's output from a given source of
  66  // bytes, wrapped in brackets [].
  67  func AppendBracket(dst, src []byte, ac AppendBytesClosure) []byte {
  68  	dst = append(dst, '[')
  69  	dst = ac(dst, src)
  70  	dst = append(dst, ']')
  71  	return dst
  72  }
  73  
  74  // AppendList appends an input source bytes processed by an AppendBytesClosure and separates
  75  // elements with the given separator byte.
  76  func AppendList(
  77  	dst []byte, src [][]byte, separator byte,
  78  	ac AppendBytesClosure,
  79  ) []byte {
  80  	// Pre-allocate buffer if nil to reduce reallocations
  81  	// Estimate: sum of all source sizes + separators
  82  	if dst == nil && len(src) > 0 {
  83  		estimatedSize := len(src) - 1 // separators
  84  		for i := range src {
  85  			estimatedSize += len(src[i]) * 2 // worst case with escaping
  86  		}
  87  		dst = make([]byte, 0, estimatedSize)
  88  	}
  89  	last := len(src) - 1
  90  	for i := range src {
  91  		dst = ac(dst, src[i])
  92  		if i < last {
  93  			dst = append(dst, separator)
  94  		}
  95  	}
  96  	return dst
  97  }
  98