github.com/Nigel2392/go-datastructures@v1.1.5/stringbuilder/stringbuilder.go (about)

     1  package stringbuilder
     2  
     3  import (
     4  	"io"
     5  	"strings"
     6  
     7  	"github.com/Nigel2392/go-datastructures/linkedlist"
     8  )
     9  
    10  // A string builder implemented with a linked list.
    11  //
    12  // This is a wrapper around a linkedlist.Doubly[string].
    13  type StringBuilder struct {
    14  	linkedlist.Doubly[string]
    15  	len int
    16  }
    17  
    18  // Len returns the length of the string builder.
    19  func (sb *StringBuilder) Len() int {
    20  	return sb.len
    21  }
    22  
    23  // Append a string to the end of the string builder.
    24  func (sb *StringBuilder) Append(s string) {
    25  	sb.len += len(s)
    26  	sb.Doubly.Append(s)
    27  }
    28  
    29  // Prepend a string to the beginning of the string builder.
    30  func (sb *StringBuilder) Prepend(s string) {
    31  	sb.len += len(s)
    32  	sb.Doubly.Prepend(s)
    33  }
    34  
    35  // Reset the string builder.
    36  //
    37  // This will clear the string builders internal nodes.
    38  func (sb *StringBuilder) Reset() {
    39  	sb.len = 0
    40  	sb.Doubly.Reset()
    41  }
    42  
    43  // Returns the string builder as a string.
    44  func (sb *StringBuilder) String() string {
    45  	var (
    46  		i int
    47  		n *linkedlist.DoublyNode[string]
    48  	)
    49  	var rs = make([]byte, sb.len)
    50  	for n = sb.Doubly.Head(); n != nil; n = n.Next() {
    51  		i += copy(rs[i:], n.Value())
    52  	}
    53  	return string(rs)
    54  }
    55  
    56  // Checks if the stringbuilder contains the given string.
    57  //
    58  // It will allocate a new string to check if the stringbuilder contains the given string.
    59  func (sb *StringBuilder) Contains(s string) bool {
    60  	return strings.Contains(sb.String(), s)
    61  }
    62  
    63  // Functionality for the Stringer interface.
    64  func (sb *StringBuilder) GoString() string {
    65  	return sb.String()
    66  }
    67  
    68  // Implement io.Writer.
    69  //
    70  // Appends to the end of the stringbuilder.
    71  func (sb *StringBuilder) Write(p []byte) (n int, err error) {
    72  	sb.Append(string(p))
    73  	return len(p), nil
    74  }
    75  
    76  // Implement io.ByteWriter.
    77  //
    78  // Appends to the end of the stringbuilder.
    79  func (sb *StringBuilder) WriteByte(c byte) error {
    80  	sb.Append(string(c))
    81  	return nil
    82  }
    83  
    84  // Implement io.RuneWriter.
    85  //
    86  // Appends to the end of the stringbuilder.
    87  func (sb *StringBuilder) WriteRune(r rune) (n int, err error) {
    88  	sb.Append(string(r))
    89  	return 1, nil
    90  }
    91  
    92  // Implement io.StringWriter.
    93  //
    94  // Appends to the end of the stringbuilder.
    95  func (sb *StringBuilder) WriteString(s string) (n int, err error) {
    96  	sb.Append(s)
    97  	return len(s), nil
    98  }
    99  
   100  type Grower interface {
   101  	Grow(n int)
   102  }
   103  
   104  // Implement io.WriterTo.
   105  //
   106  // Writes the stringbuilder to the io.Writer.
   107  func (sb *StringBuilder) WriteTo(w io.Writer) (n int64, err error) {
   108  	var (
   109  		node *linkedlist.DoublyNode[string]
   110  	)
   111  
   112  	if g, ok := w.(Grower); ok {
   113  		g.Grow(sb.len)
   114  	}
   115  
   116  	for node = sb.Doubly.Head(); node != nil; node = node.Next() {
   117  		var nn int
   118  		nn, err = w.Write([]byte(node.Value()))
   119  		n += int64(nn)
   120  		if err != nil {
   121  			return
   122  		}
   123  	}
   124  	return
   125  }