Skip to content

Commit 16a1113

Browse files
committed
all: backend str, bytes in struct wrappers
to workaround github.com/golang/go/issues/46893
1 parent c897a7a commit 16a1113

63 files changed

Lines changed: 1059 additions & 657 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

intra/backend/core_boxes.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// Copyright (c) 2025 RethinkDNS and its authors.
2+
//
3+
// This Source Code Form is subject to the terms of the Mozilla Public
4+
// License, v. 2.0. If a copy of the MPL was not distributed with this
5+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
7+
package backend
8+
9+
import (
10+
"sync"
11+
"unique"
12+
"weak"
13+
)
14+
15+
const internstr = true
16+
17+
var (
18+
internmu = new(sync.Mutex)
19+
interns = make(map[unique.Handle[string]]weak.Pointer[Gostr])
20+
)
21+
22+
// Gostr & Gobytes are a workaround for:
23+
// github.com/golang/go/issues/46893
24+
25+
type Gostr struct {
26+
v unique.Handle[string]
27+
}
28+
29+
func (s *Gostr) String() string {
30+
return s.V()
31+
}
32+
33+
func StrOf(v string) (r *Gostr) {
34+
if len(v) == 0 {
35+
return nil
36+
}
37+
38+
// go.dev/play/p/LFqxCEZSo62
39+
hdl := unique.Make(v)
40+
if internstr {
41+
internmu.Lock()
42+
defer internmu.Unlock()
43+
44+
if s, ok := interns[hdl]; ok {
45+
r = s.Value()
46+
}
47+
if r == nil {
48+
r = &Gostr{v: hdl}
49+
interns[hdl] = weak.Make(r)
50+
}
51+
52+
return r
53+
}
54+
return &Gostr{v: hdl}
55+
}
56+
57+
func (s *Gostr) V() string {
58+
if s == nil {
59+
return ""
60+
}
61+
return s.v.Value()
62+
}
63+
64+
func (s *Gostr) Len() int {
65+
return len(s.V())
66+
}
67+
68+
func OfFunc[T *Gostr | *Gobyte, R string | []byte](f func() (R, error)) (T, error) {
69+
v, err := f()
70+
if err != nil {
71+
return nil, err
72+
}
73+
switch any(v).(type) {
74+
case string:
75+
if str, ok := any(v).(string); ok {
76+
return any(StrOf(str)).(T), nil
77+
}
78+
case []byte:
79+
if bytes, ok := any(v).([]byte); ok {
80+
return any(BytesOf(bytes)).(T), nil
81+
}
82+
}
83+
var zero T
84+
return zero, nil
85+
}
86+
87+
func StrOfFunc(f func() (string, error)) (*Gostr, error) {
88+
s, err := f()
89+
if err != nil {
90+
return nil, err
91+
}
92+
return StrOf(s), nil
93+
}
94+
95+
func StrOfFunc1[P any](f func(P) (string, error), p P) (*Gostr, error) {
96+
s, err := f(p)
97+
if err != nil {
98+
return nil, err
99+
}
100+
return StrOf(s), nil
101+
}
102+
103+
func StrOfFunc2[P any, Q any](f func(P, Q) (string, error), p P, q Q) (*Gostr, error) {
104+
s, err := f(p, q)
105+
if err != nil {
106+
return nil, err
107+
}
108+
return StrOf(s), nil
109+
}
110+
111+
type Gobyte struct {
112+
v []byte
113+
}
114+
115+
func BytesOf(v []byte) *Gobyte {
116+
return &Gobyte{v: v}
117+
}
118+
119+
func (b *Gobyte) V() []byte {
120+
if b == nil {
121+
return nil
122+
}
123+
return b.v
124+
}
125+
126+
func (b *Gobyte) Len() int {
127+
return len(b.V())
128+
}
129+
130+
func BytesOfFunc(f func() ([]byte, error)) (*Gobyte, error) {
131+
s, err := f()
132+
if err != nil {
133+
return nil, err
134+
}
135+
return BytesOf(s), nil
136+
}

0 commit comments

Comments
 (0)