Skip to content

Commit 7d3629a

Browse files
committed
detach a string if the attached data is nil
1 parent 6ce9ac1 commit 7d3629a

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This `magicstring` package is designed to attach arbitrary data to a Go built-in
1111

1212
### Attach data and then read it
1313

14-
Call `Attach` to attach data into a string and `Read` to read the attached data in the magic string.
14+
Call `Attach` to attach data to a string and `Read` to read the attached data in the magic string.
1515

1616
```go
1717
type T struct {

attachment.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ import (
99
"unsafe"
1010
)
1111

12-
// Attach associates the data with a newly allocated string.
12+
// Attach associates a newly allocated string with data.
1313
// The value of the returned string is guaranteed to be identical to str.
14+
//
15+
// Calling `Attach(str, nil)` is equivalent to `Detach(str)`.
1416
func Attach(str string, data interface{}) string {
17+
if data == nil {
18+
return Detach(str)
19+
}
20+
1521
sz := len(str)
1622

1723
if sz == 0 {

attachment_test.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ package magicstring
55

66
import (
77
"fmt"
8+
"reflect"
89
"testing"
10+
"unsafe"
911

1012
"github.com/huandu/go-assert"
1113
)
1214

1315
func TestAttachData(t *testing.T) {
1416
a := assert.New(t)
1517
cases := []interface{}{
16-
1, "abcd", true, nil, 1.2, complex(1, 2),
18+
1, "abcd", true, 1.2, complex(1, 2),
1719
struct{}{}, []byte("123"), &testStruct{},
1820
map[string][]int{"foo": {1, 2, 3}},
1921
}
@@ -30,6 +32,30 @@ func TestAttachData(t *testing.T) {
3032
}
3133
}
3234

35+
func TestAttachNilData(t *testing.T) {
36+
a := assert.New(t)
37+
s1 := "nil data"
38+
s2 := Attach(s1, nil)
39+
s3 := Attach(s1, 123)
40+
s4 := Attach(s3, nil)
41+
a.Equal(s1, s2)
42+
a.Equal(s1, s3)
43+
a.Equal(s1, s4)
44+
45+
// There is no magic attached to s2.
46+
a.Assert(!Is(s2))
47+
48+
// The buffer in s1 and s2 must be identical.
49+
data1 := (*reflect.StringHeader)(unsafe.Pointer(&s1)).Data
50+
data2 := (*reflect.StringHeader)(unsafe.Pointer(&s2)).Data
51+
a.Equal(data1, data2)
52+
53+
// The buffer in s3 and s4 must be different.
54+
data3 := (*reflect.StringHeader)(unsafe.Pointer(&s3)).Data
55+
data4 := (*reflect.StringHeader)(unsafe.Pointer(&s4)).Data
56+
a.NotEqual(data3, data4)
57+
}
58+
3359
func TestReadInvalidString(t *testing.T) {
3460
a := assert.New(t)
3561
s := "dummy"

0 commit comments

Comments
 (0)