Skip to content

Commit 3ddd389

Browse files
committed
feat: Add support for counting bytes in strings.
1 parent 79d1647 commit 3ddd389

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

corefunc/str_byte_length.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2023-2024, Northwood Labs
2+
// Copyright 2023-2024, Ryan Parman <[email protected]>
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package corefunc
17+
18+
import "github.com/mattn/go-runewidth"
19+
20+
/*
21+
StrByteLength returns the number of bytes/runes in a string. This is different
22+
from the number of characters, which is what Terraform and OpenTofu's `length()`
23+
function returns for strings.
24+
25+
----
26+
27+
- str (string): The string with which to count bytes/runes.
28+
*/
29+
func StrByteLength(str string) int {
30+
return runewidth.StringWidth(str)
31+
}

corefunc/str_byte_length_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2023-2024, Northwood Labs
2+
// Copyright 2023-2024, Ryan Parman <[email protected]>
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package corefunc
17+
18+
import (
19+
"fmt"
20+
"testing"
21+
22+
"github.com/northwood-labs/terraform-provider-corefunc/testfixtures"
23+
)
24+
25+
func ExampleStrByteLength() {
26+
output := StrByteLength("abcde")
27+
fmt.Println(output)
28+
29+
output = StrByteLength("\x00")
30+
fmt.Println(output)
31+
32+
output = StrByteLength("👁")
33+
fmt.Println(output)
34+
35+
output = StrByteLength("■㈱の世界①")
36+
fmt.Println(output)
37+
38+
// Output:
39+
// 5
40+
// 0
41+
// 1
42+
// 10
43+
}
44+
45+
func TestStrByteLength(t *testing.T) { // lint:allow_complexity
46+
for name, tc := range testfixtures.StrByteLengthTestTable {
47+
t.Run(name, func(t *testing.T) {
48+
output := StrByteLength(tc.Input)
49+
50+
if output != tc.Expected {
51+
t.Errorf("Expected %d, got %d", tc.Expected, output)
52+
}
53+
})
54+
}
55+
}

testfixtures/str_byte_length.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2023-2024, Northwood Labs
2+
// Copyright 2023-2024, Ryan Parman <[email protected]>
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package testfixtures // lint:no_dupe
17+
18+
// StrByteLengthTestTable is used by both the standard Go tests and also the
19+
// Terraform acceptance tests.
20+
// <https://github.com/golang/go/wiki/TableDrivenTests>
21+
var StrByteLengthTestTable = map[string]struct { // lint:no_dupe
22+
Input string
23+
Expected int
24+
}{
25+
"blank": {"", 0},
26+
"abcde": {"abcde", 5},
27+
"世": {"世", 2},
28+
"界": {"界", 2},
29+
"セ": {"セ", 1},
30+
"カ": {"カ", 1},
31+
"イ": {"イ", 1},
32+
"☆": {"☆", 1},
33+
"☺": {"☺", 1},
34+
"☻": {"☻", 1},
35+
"♥": {"♥", 1},
36+
"♦": {"♦", 1},
37+
"♣": {"♣", 1},
38+
"♠": {"♠", 1},
39+
"♂": {"♂", 1},
40+
"♀": {"♀", 1},
41+
"♪": {"♪", 1},
42+
"♫": {"♫", 1},
43+
"☼": {"☼", 1},
44+
"↕": {"↕", 1},
45+
"‼": {"‼", 1},
46+
"↔": {"↔", 1},
47+
"\x00": {"\x00", 0},
48+
"\x01": {"\x01", 0},
49+
"\u0300": {"\u0300", 0},
50+
"\u2028": {"\u2028", 0},
51+
"\u2029": {"\u2029", 0},
52+
"a": {"a", 1},
53+
"⟦": {"⟦", 1},
54+
"👁": {"👁", 1},
55+
"■㈱の世界①": {"■㈱の世界①", 10},
56+
"スター☆": {"スター☆", 7},
57+
"つのだ☆HIRO": {"つのだ☆HIRO", 11},
58+
}

0 commit comments

Comments
 (0)