Skip to content

Commit 202a72f

Browse files
committed
feat: StringBuilder uses builder pattern
1 parent 9499fc4 commit 202a72f

File tree

2 files changed

+37
-27
lines changed

2 files changed

+37
-27
lines changed

stringbuilder.go

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func NewStringBuilderFromString(text string) *StringBuilder {
2222
}
2323

2424
// Appends a text to the StringBuilder instance
25-
func (s *StringBuilder) Append(text string) {
25+
func (s *StringBuilder) Append(text string) *StringBuilder {
2626
textRunes := []rune(text)
2727
newLen := s.position + len(textRunes)
2828
if newLen > cap(s.data) {
@@ -31,23 +31,29 @@ func (s *StringBuilder) Append(text string) {
3131

3232
copy(s.data[s.position:], textRunes)
3333
s.position = newLen
34+
35+
return s
3436
}
3537

3638
// Appends a text and a new line character to the StringBuilder instance
37-
func (s *StringBuilder) AppendLine(text string) {
39+
func (s *StringBuilder) AppendLine(text string) *StringBuilder {
3840
s.Append(text)
3941
s.Append("\n")
42+
43+
return s
4044
}
4145

4246
// Appends a single character to the StringBuilder instance
43-
func (s *StringBuilder) AppendRune(char rune) {
47+
func (s *StringBuilder) AppendRune(char rune) *StringBuilder {
4448
newLen := s.position + 1
4549
if newLen > cap(s.data) {
4650
s.grow(newLen)
4751
}
4852

4953
s.data[s.position] = char
5054
s.position++
55+
56+
return s
5157
}
5258

5359
// Returns the current length of the represented string
@@ -60,41 +66,41 @@ func (s *StringBuilder) ToString() string {
6066
return string(s.data[:s.position])
6167
}
6268

63-
func (s *StringBuilder) Remove(start int, length int) error {
69+
func (s *StringBuilder) Remove(start int, length int) (*StringBuilder, error) {
6470
if start >= s.position {
65-
return fmt.Errorf("start is after the end of the string")
71+
return s, fmt.Errorf("start is after the end of the string")
6672
}
6773
if start < 0 {
68-
return fmt.Errorf("start can't be a negative value")
74+
return s, fmt.Errorf("start can't be a negative value")
6975
}
7076
if length < 0 {
71-
return fmt.Errorf("length can't be a negative value")
77+
return s, fmt.Errorf("length can't be a negative value")
7278
}
7379

7480
endIndex := start + length - 1
7581

7682
if endIndex > s.position {
77-
return fmt.Errorf("can't delete after the end of the string")
83+
return s, fmt.Errorf("can't delete after the end of the string")
7884
}
7985

8086
if length == 0 {
81-
return nil
87+
return s, nil
8288
}
8389

8490
x := start + length
8591
copy(s.data[start:], s.data[x:])
8692
s.position -= length
8793

88-
return nil
94+
return s, nil
8995
}
9096

91-
func (s *StringBuilder) Insert(index int, text string) error {
97+
func (s *StringBuilder) Insert(index int, text string) (*StringBuilder, error) {
9298
if index < 0 {
93-
return fmt.Errorf("index can't be negative")
99+
return s, fmt.Errorf("index can't be negative")
94100
}
95101

96102
if index > s.position {
97-
return fmt.Errorf("can't write outside the buffer")
103+
return s, fmt.Errorf("can't write outside the buffer")
98104
}
99105

100106
runeText := []rune(text)
@@ -106,7 +112,7 @@ func (s *StringBuilder) Insert(index int, text string) error {
106112
s.data = append(s.data[:index], append(runeText, s.data[index:]...)...)
107113
s.position = newLen
108114

109-
return nil
115+
return s, nil
110116
}
111117

112118
// Removes all characters from the current instance. This sets the internal size to 0.
@@ -142,18 +148,20 @@ func (s *StringBuilder) FindAll(text string) []int {
142148
}
143149

144150
// Replaces all occurrences of oldValue with newValue
145-
func (s *StringBuilder) ReplaceRune(oldValue rune, newValue rune) {
151+
func (s *StringBuilder) ReplaceRune(oldValue rune, newValue rune) *StringBuilder {
146152
occurrences := s.FindAll(string(oldValue))
147153

148154
for _, v := range occurrences {
149155
s.data[v] = newValue
150156
}
157+
158+
return s
151159
}
152160

153161
// Replaces all occurrences of oldValue with newValue
154-
func (s *StringBuilder) Replace(oldValue string, newValue string) {
162+
func (s *StringBuilder) Replace(oldValue string, newValue string) *StringBuilder {
155163
if oldValue == newValue {
156-
return
164+
return s
157165
}
158166

159167
occurrences := s.FindAll(oldValue)
@@ -183,6 +191,8 @@ func (s *StringBuilder) Replace(oldValue string, newValue string) {
183191
s.Insert(index+oldLen, string(newValueRunes[len(oldValueRunes):]))
184192
}
185193
}
194+
195+
return s
186196
}
187197

188198
// Implements the io.Writer interface so the StringBuilder can be used with fmt.Printf

stringbuilder_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func TestNewFromString(t *testing.T) {
9292
func TestRemovePartOfString(t *testing.T) {
9393
sb := NewStringBuilderFromString("Hello")
9494

95-
if err := sb.Remove(3, 2); err != nil {
95+
if _, err := sb.Remove(3, 2); err != nil {
9696
t.Errorf("Remove threw an error: %v", err)
9797
}
9898

@@ -104,31 +104,31 @@ func TestRemovePartOfString(t *testing.T) {
104104
func TestRemoveWhenStartIndexOutOfBounds(t *testing.T) {
105105
sb := NewStringBuilderFromString("Hello")
106106

107-
if err := sb.Remove(100, 1); err == nil {
107+
if _, err := sb.Remove(100, 1); err == nil {
108108
t.Error("Should throw error but did not")
109109
}
110110
}
111111

112112
func TestRemoveWhenStartIndexNegative(t *testing.T) {
113113
sb := NewStringBuilderFromString("Hello")
114114

115-
if err := sb.Remove(-1, 1); err == nil {
115+
if _, err := sb.Remove(-1, 1); err == nil {
116116
t.Error("Should throw error but did not")
117117
}
118118
}
119119

120120
func TestRemoveWhenLengthNegative(t *testing.T) {
121121
sb := NewStringBuilderFromString("Hello")
122122

123-
if err := sb.Remove(1, -1); err == nil {
123+
if _, err := sb.Remove(1, -1); err == nil {
124124
t.Error("Should throw error but did not")
125125
}
126126
}
127127

128128
func TestRemoveWhenEndIndexOutOfBounds(t *testing.T) {
129129
sb := NewStringBuilderFromString("Hello")
130130

131-
if err := sb.Remove(4, 4); err == nil {
131+
if _, err := sb.Remove(4, 4); err == nil {
132132
t.Error("Should throw error but did not")
133133
}
134134
}
@@ -137,7 +137,7 @@ func TestRemoveWhenLengthZero(t *testing.T) {
137137
const expected string = "Hello"
138138
sb := NewStringBuilderFromString(expected)
139139

140-
if err := sb.Remove(0, 0); err != nil {
140+
if _, err := sb.Remove(0, 0); err != nil {
141141
t.Errorf("Remove threw an error: %v", err)
142142
}
143143

@@ -150,7 +150,7 @@ func TestRemoveInTheMiddle(t *testing.T) {
150150
const expected string = "Hlo World"
151151
sb := NewStringBuilderFromString("Hello World")
152152

153-
if err := sb.Remove(1, 2); err != nil {
153+
if _, err := sb.Remove(1, 2); err != nil {
154154
t.Errorf("Remove threw an error: %v", err)
155155
}
156156

@@ -163,7 +163,7 @@ func TestInsertAtIndex(t *testing.T) {
163163
const expected string = "Hello my dear and beautiful World"
164164
sb := NewStringBuilderFromString("Hello World")
165165

166-
if err := sb.Insert(5, " my dear and beautiful"); err != nil {
166+
if _, err := sb.Insert(5, " my dear and beautiful"); err != nil {
167167
t.Errorf("Insert threw an error: %v", err)
168168
}
169169

@@ -175,15 +175,15 @@ func TestInsertAtIndex(t *testing.T) {
175175
func TestInsertShouldThrowIfNegativeIndex(t *testing.T) {
176176
sb := StringBuilder{}
177177

178-
if err := sb.Insert(-1, "Test"); err == nil {
178+
if _, err := sb.Insert(-1, "Test"); err == nil {
179179
t.Error("Should throw error but did not")
180180
}
181181
}
182182

183183
func TestInsertShouldThrowErrirIfOutOfRange(t *testing.T) {
184184
sb := StringBuilder{}
185185

186-
if err := sb.Insert(1, "Test"); err == nil {
186+
if _, err := sb.Insert(1, "Test"); err == nil {
187187
t.Error("Should throw error but did not")
188188
}
189189
}

0 commit comments

Comments
 (0)