Skip to content

Commit 308fc36

Browse files
committed
feat: add strings package
1 parent 590ed97 commit 308fc36

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

strings/strings.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package strings
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"cmp"
7+
"strings"
8+
"unicode/utf8"
9+
)
10+
11+
// Dedent attempts to determine the indent-level from the first non-empty line,
12+
// and trims the indents from all lines.
13+
func Dedent(s string) string {
14+
scanner := bufio.NewScanner(strings.NewReader(s))
15+
var indent []byte
16+
var b bytes.Buffer
17+
for scanner.Scan() {
18+
line := scanner.Bytes()
19+
if len(line) == 0 {
20+
continue
21+
}
22+
if indent == nil {
23+
indent = detect(line).Bytes()
24+
}
25+
line = bytes.TrimPrefix(line, indent)
26+
if len(bytes.TrimSpace(line)) == 0 {
27+
continue
28+
}
29+
b.Write(line)
30+
b.WriteRune('\n')
31+
}
32+
return b.String()
33+
}
34+
35+
func detect(line []byte) (indent indent) {
36+
if len(line) == 0 {
37+
return
38+
}
39+
switch rune(line[0]) {
40+
case '\t':
41+
indent.c = rune(line[0])
42+
indent.n += 1
43+
case ' ':
44+
indent.c = rune(line[0])
45+
indent.n += 1
46+
default:
47+
return
48+
}
49+
for _, r := range line[1:] {
50+
if rune(r) != indent.c {
51+
return
52+
}
53+
indent.n += 1
54+
}
55+
return
56+
}
57+
58+
type indent struct {
59+
c rune
60+
n int
61+
}
62+
63+
func (i indent) Len() int {
64+
return cmp.Or(i.n, 0)
65+
}
66+
67+
func (i indent) Bytes() []byte {
68+
return bytes.Repeat(utf8.AppendRune(nil, i.c), i.n)
69+
}

strings/strings_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package strings
2+
3+
import (
4+
"testing"
5+
6+
"go.chrisrx.dev/x/assert"
7+
)
8+
9+
func TestDedent(t *testing.T) {
10+
s := Dedent(`
11+
SELECT
12+
*
13+
FROM
14+
table t1
15+
WHERE
16+
status = 'ok'
17+
AND something <> 'lol'
18+
`)
19+
20+
assert.Equal(t, `SELECT
21+
*
22+
FROM
23+
table t1
24+
WHERE
25+
status = 'ok'
26+
AND something <> 'lol'
27+
`, s)
28+
}

0 commit comments

Comments
 (0)