gofront 1.8.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/package.json +6 -5
- package/src/backend/js/expressions.js +1157 -408
- package/src/backend/js/index.js +327 -153
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +559 -2552
- package/src/backend/js/statements.js +670 -158
- package/src/backend/js/stdlib/index.js +45 -93
- package/src/backend/js/templ.js +32 -45
- package/src/backend/js/type-info.js +298 -19
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +91 -170
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +490 -965
- package/src/backend/wasm/emit-builtins.js +884 -256
- package/src/backend/wasm/emit-exprs.js +185 -77
- package/src/backend/wasm/emit-maps.js +17 -367
- package/src/backend/wasm/emit-shared.js +4 -1
- package/src/backend/wasm/emit-stmts.js +524 -240
- package/src/backend/wasm/emit.js +176 -38
- package/src/backend/wasm/globals.js +48 -8
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +44 -530
- package/src/backend/wasm/method-expr.js +12 -1
- package/src/backend/wasm/module-emitter.js +299 -770
- package/src/backend/wasm/monomorph.js +139 -8
- package/src/backend/wasm/natives.js +600 -0
- package/src/backend/wasm/prescan.js +5 -153
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -32
- package/src/backend/wasm/types.js +97 -20
- package/src/backend/wasm/variadic.js +9 -4
- package/src/cli/cli-core.js +5 -1
- package/src/cli/test-runner.js +115 -342
- package/src/compiler.js +113 -130
- package/src/lexer/lexer.js +106 -11
- package/src/lexer/templ-lexer.js +61 -18
- package/src/lexer/tokens.js +1 -0
- package/src/link/stdlib.js +355 -132
- package/src/link/type-names.js +204 -0
- package/src/link/wasm.js +30 -6
- package/src/lower/bounds.js +153 -0
- package/src/lower/captures.js +92 -33
- package/src/lower/embedding.js +62 -5
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +929 -0
- package/src/lower/functions.js +225 -7
- package/src/lower/gen-types.js +293 -0
- package/src/lower/index.js +14 -2
- package/src/lower/json-codecs.js +334 -245
- package/src/lower/ownership.js +25 -7
- package/src/lower/reachability.js +69 -51
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +30 -5
- package/src/parser/expressions.js +111 -57
- package/src/parser/statements.js +108 -0
- package/src/parser/templ.js +44 -5
- package/src/parser/types.js +12 -0
- package/src/resolver.js +1 -2
- package/src/typechecker/assignability.js +214 -19
- package/src/typechecker/const-fold.js +70 -27
- package/src/typechecker/constants.js +156 -8
- package/src/typechecker/expressions.js +490 -108
- package/src/typechecker/index.js +346 -42
- package/src/typechecker/init-order.js +136 -40
- package/src/typechecker/operand-text.js +41 -0
- package/src/typechecker/resolve.js +490 -65
- package/src/typechecker/statements.js +288 -27
- package/src/typechecker/stdlib/excluded.js +9 -5
- package/src/typechecker/stdlib/index.js +25 -9
- package/src/typechecker/termination.js +10 -1
- package/src/typechecker/types.js +287 -575
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -0
- package/stdlib/context/context.go +115 -0
- package/stdlib/crypto/rand/rand.go +34 -0
- package/stdlib/crypto/sha256/sha256.go +249 -0
- package/stdlib/encoding/base64/base64.go +331 -0
- package/stdlib/encoding/binary/binary.go +332 -0
- package/stdlib/encoding/hex/hex.go +140 -0
- package/stdlib/encoding/json/json.go +62 -0
- package/stdlib/errors/errors.go +174 -0
- package/stdlib/fmt/errors.go +110 -0
- package/stdlib/fmt/format.go +732 -0
- package/stdlib/fmt/print.go +1232 -0
- package/stdlib/gom/gom.go +293 -0
- package/stdlib/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +171 -38
- package/stdlib/internal/jsonrt/enc.go +186 -36
- package/stdlib/internal/jsonrt/scanner.go +17 -8
- package/stdlib/io/io.go +157 -1
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +16 -14
- package/stdlib/math/math.go +439 -0
- package/stdlib/math/rand/rand.go +297 -0
- package/stdlib/os/os.go +93 -0
- package/stdlib/path/filepath/filepath.go +47 -0
- package/stdlib/path/path.go +394 -0
- package/stdlib/regexp/regexp.go +231 -0
- package/stdlib/slices/slices.go +526 -0
- package/stdlib/slices/sort.go +209 -0
- package/stdlib/slices/zsort_cmp.go +480 -0
- package/stdlib/slices/zsort_ordered.go +482 -0
- package/stdlib/sort/sort.go +391 -452
- package/stdlib/sort/zsort_func.go +480 -0
- package/stdlib/sort/zsort_iface.go +480 -0
- package/stdlib/strconv/float.go +1699 -0
- package/stdlib/strconv/isprint.go +752 -0
- package/stdlib/strconv/quote.go +235 -50
- package/stdlib/strconv/strconv.go +616 -0
- package/stdlib/strings/builder.go +95 -0
- package/stdlib/strings/reader.go +163 -0
- package/stdlib/strings/replacer.go +102 -0
- package/stdlib/strings/strings.go +807 -0
- package/stdlib/sync/sync.go +268 -0
- package/stdlib/testing/async_js.go +61 -0
- package/stdlib/testing/benchmark.go +297 -0
- package/stdlib/testing/testing.go +523 -0
- package/stdlib/time/duration.go +233 -0
- package/stdlib/time/format.go +745 -0
- package/stdlib/time/parse.go +790 -0
- package/stdlib/time/sleep_js.go +63 -0
- package/stdlib/time/time.go +834 -0
- package/stdlib/unicode/unicode.go +141 -3
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/fmt-runtime.js +0 -573
- package/src/backend/js/stdlib/base64.js +0 -12
- package/src/backend/js/stdlib/binary.js +0 -102
- package/src/backend/js/stdlib/bits.js +0 -119
- package/src/backend/js/stdlib/builder.js +0 -98
- package/src/backend/js/stdlib/bytes.js +0 -368
- package/src/backend/js/stdlib/errors.js +0 -45
- package/src/backend/js/stdlib/fmt.js +0 -517
- package/src/backend/js/stdlib/gom.js +0 -155
- package/src/backend/js/stdlib/hex.js +0 -17
- package/src/backend/js/stdlib/html.js +0 -20
- package/src/backend/js/stdlib/io.js +0 -137
- package/src/backend/js/stdlib/json.js +0 -1167
- package/src/backend/js/stdlib/maps.js +0 -37
- package/src/backend/js/stdlib/math.js +0 -85
- package/src/backend/js/stdlib/os.js +0 -13
- package/src/backend/js/stdlib/path.js +0 -48
- package/src/backend/js/stdlib/rand.js +0 -32
- package/src/backend/js/stdlib/regexp.js +0 -54
- package/src/backend/js/stdlib/sha256.js +0 -12
- package/src/backend/js/stdlib/shared.js +0 -17
- package/src/backend/js/stdlib/simd.js +0 -34
- package/src/backend/js/stdlib/slices.js +0 -107
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -79
- package/src/backend/js/stdlib/strings.js +0 -301
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -41
- package/src/backend/js/stdlib/time.js +0 -152
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/stdlib/bytes.js +0 -6716
- package/src/backend/wasm/stdlib/core.js +0 -10278
- package/src/backend/wasm/stdlib/io.js +0 -3578
- package/src/backend/wasm/stdlib/packages.js +0 -2402
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -2229
- package/src/typechecker/stdlib/core.js +0 -1079
- package/src/typechecker/stdlib/extended.js +0 -1210
- package/stdlib/bytes/iter.go +0 -192
- package/stdlib/bytes/search.go +0 -240
- package/stdlib/bytes/split.go +0 -218
- package/stdlib/errors/overlay.go +0 -12
- package/stdlib/maps/iter.go +0 -65
- package/stdlib/slices/extra.go +0 -73
- package/stdlib/slices/iter.go +0 -113
- package/stdlib/strings/extra.go +0 -35
- package/stdlib/strings/iter.go +0 -122
- package/stdlib/sync/extra.go +0 -105
- package/stdlib/unicode/utf8/bytes.go +0 -239
|
@@ -71,7 +71,9 @@ type scanner struct {
|
|
|
71
71
|
endTop bool
|
|
72
72
|
|
|
73
73
|
// Stack of what we're in the middle of - array values, object keys, object values.
|
|
74
|
-
|
|
74
|
+
// Only the first parseStateLen entries are live; the rest is reused room.
|
|
75
|
+
parseState []int
|
|
76
|
+
parseStateLen int
|
|
75
77
|
|
|
76
78
|
// Error that happened, if any.
|
|
77
79
|
err error
|
|
@@ -130,7 +132,7 @@ const maxNestingDepth = 10000
|
|
|
130
132
|
// It must be called before calling s.step.
|
|
131
133
|
func (s *scanner) reset() {
|
|
132
134
|
s.step = stateBeginValue
|
|
133
|
-
s.
|
|
135
|
+
s.parseStateLen = 0
|
|
134
136
|
s.err = nil
|
|
135
137
|
s.endTop = false
|
|
136
138
|
}
|
|
@@ -157,8 +159,13 @@ func (s *scanner) eof() int {
|
|
|
157
159
|
// pushParseState pushes a new parse state newParseState onto the parse stack.
|
|
158
160
|
// an error state is returned if maxNestingDepth was exceeded, otherwise successState is returned.
|
|
159
161
|
func (s *scanner) pushParseState(c byte, newParseState int, successState int) int {
|
|
160
|
-
s.
|
|
161
|
-
|
|
162
|
+
if s.parseStateLen < len(s.parseState) {
|
|
163
|
+
s.parseState[s.parseStateLen] = newParseState
|
|
164
|
+
} else {
|
|
165
|
+
s.parseState = append(s.parseState, newParseState)
|
|
166
|
+
}
|
|
167
|
+
s.parseStateLen++
|
|
168
|
+
if s.parseStateLen <= maxNestingDepth {
|
|
162
169
|
return successState
|
|
163
170
|
}
|
|
164
171
|
return s.error(c, "exceeded max depth")
|
|
@@ -167,8 +174,8 @@ func (s *scanner) pushParseState(c byte, newParseState int, successState int) in
|
|
|
167
174
|
// popParseState pops a parse state (already obtained) off the stack
|
|
168
175
|
// and updates s.step accordingly.
|
|
169
176
|
func (s *scanner) popParseState() {
|
|
170
|
-
|
|
171
|
-
|
|
177
|
+
s.parseStateLen--
|
|
178
|
+
n := s.parseStateLen
|
|
172
179
|
if n == 0 {
|
|
173
180
|
s.step = stateEndTop
|
|
174
181
|
s.endTop = true
|
|
@@ -236,7 +243,7 @@ func stateBeginStringOrEmpty(s *scanner, c byte) int {
|
|
|
236
243
|
return scanSkipSpace
|
|
237
244
|
}
|
|
238
245
|
if c == '}' {
|
|
239
|
-
n :=
|
|
246
|
+
n := s.parseStateLen
|
|
240
247
|
s.parseState[n-1] = parseObjectValue
|
|
241
248
|
return stateEndValue(s, c)
|
|
242
249
|
}
|
|
@@ -258,7 +265,7 @@ func stateBeginString(s *scanner, c byte) int {
|
|
|
258
265
|
// stateEndValue is the state after completing a value,
|
|
259
266
|
// such as after reading `{}` or `true` or `["x"`.
|
|
260
267
|
func stateEndValue(s *scanner, c byte) int {
|
|
261
|
-
n :=
|
|
268
|
+
n := s.parseStateLen
|
|
262
269
|
if n == 0 {
|
|
263
270
|
// Completed top-level before the current byte.
|
|
264
271
|
s.step = stateEndTop
|
|
@@ -592,6 +599,8 @@ func quoteChar(c byte) string {
|
|
|
592
599
|
|
|
593
600
|
// CheckValid returns nil when data is one valid JSON value, else the
|
|
594
601
|
// *SyntaxError describing the first problem.
|
|
602
|
+
//
|
|
603
|
+
//gofront:native jsonrt.CheckValid
|
|
595
604
|
func CheckValid(data []byte) error {
|
|
596
605
|
return checkValid(data, newScanner())
|
|
597
606
|
}
|
package/stdlib/io/io.go
CHANGED
|
@@ -2,13 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
//gofront:target both
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// Package io provides the basic interfaces to I/O primitives, written in
|
|
6
|
+
// Go over the real package's algorithms. io.Pipe is not supported.
|
|
6
7
|
package io
|
|
7
8
|
|
|
8
9
|
import (
|
|
9
10
|
"errors"
|
|
10
11
|
)
|
|
11
12
|
|
|
13
|
+
// EOF is the error returned by Read when no more input is available.
|
|
14
|
+
var EOF = errors.New("EOF")
|
|
15
|
+
|
|
16
|
+
// Reader is the interface that wraps the basic Read method.
|
|
17
|
+
type Reader interface {
|
|
18
|
+
Read(p []byte) (n int, err error)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Writer is the interface that wraps the basic Write method.
|
|
22
|
+
type Writer interface {
|
|
23
|
+
Write(p []byte) (n int, err error)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Closer is the interface that wraps the basic Close method.
|
|
27
|
+
type Closer interface {
|
|
28
|
+
Close() error
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ReadWriter is the interface that groups the basic Read and Write methods.
|
|
32
|
+
type ReadWriter interface {
|
|
33
|
+
Reader
|
|
34
|
+
Writer
|
|
35
|
+
}
|
|
36
|
+
|
|
12
37
|
// Seek whence values.
|
|
13
38
|
const (
|
|
14
39
|
SeekStart = 0 // seek relative to the origin of the file
|
|
@@ -344,3 +369,134 @@ func (s *SectionReader) Size() int64 { return s.limit - s.base }
|
|
|
344
369
|
func (s *SectionReader) Outer() (r ReaderAt, off int64, n int64) {
|
|
345
370
|
return s.r, s.base, s.n
|
|
346
371
|
}
|
|
372
|
+
|
|
373
|
+
// WriteString writes the contents of the string s to w.
|
|
374
|
+
func WriteString(w Writer, s string) (n int, err error) {
|
|
375
|
+
if sw, ok := w.(StringWriter); ok {
|
|
376
|
+
return sw.WriteString(s)
|
|
377
|
+
}
|
|
378
|
+
return w.Write([]byte(s))
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// ReadAll reads from r until an error or EOF and returns the data it read.
|
|
382
|
+
func ReadAll(r Reader) ([]byte, error) {
|
|
383
|
+
b := make([]byte, 0, 512)
|
|
384
|
+
for {
|
|
385
|
+
n, err := r.Read(b[len(b):cap(b)])
|
|
386
|
+
b = b[:len(b)+n]
|
|
387
|
+
if err != nil {
|
|
388
|
+
if err == EOF {
|
|
389
|
+
err = nil
|
|
390
|
+
}
|
|
391
|
+
return b, err
|
|
392
|
+
}
|
|
393
|
+
if len(b) == cap(b) {
|
|
394
|
+
b = append(b, 0)[:len(b)]
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// A LimitedReader reads from R but limits the amount of data returned to just N bytes.
|
|
400
|
+
type LimitedReader struct {
|
|
401
|
+
R Reader // underlying reader
|
|
402
|
+
N int64 // max bytes remaining
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
func (l *LimitedReader) Read(p []byte) (n int, err error) {
|
|
406
|
+
if l.N <= 0 {
|
|
407
|
+
return 0, EOF
|
|
408
|
+
}
|
|
409
|
+
if int64(len(p)) > l.N {
|
|
410
|
+
p = p[0:l.N]
|
|
411
|
+
}
|
|
412
|
+
n, err = l.R.Read(p)
|
|
413
|
+
l.N -= int64(n)
|
|
414
|
+
return
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// LimitReader returns a Reader that reads from r but stops with EOF after n bytes.
|
|
418
|
+
func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
|
|
419
|
+
|
|
420
|
+
type discard struct{}
|
|
421
|
+
|
|
422
|
+
func (discard) Write(p []byte) (int, error) { return len(p), nil }
|
|
423
|
+
func (discard) WriteString(s string) (int, error) { return len(s), nil }
|
|
424
|
+
|
|
425
|
+
// Discard is a Writer on which all Write calls succeed without doing anything.
|
|
426
|
+
var Discard Writer = discard{}
|
|
427
|
+
|
|
428
|
+
// Copy copies from src to dst until either EOF is reached on src or an error occurs.
|
|
429
|
+
func Copy(dst Writer, src Reader) (written int64, err error) {
|
|
430
|
+
return copyBuffer(dst, src, nil)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// CopyN copies n bytes (or until an error) from src to dst.
|
|
434
|
+
func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
|
|
435
|
+
written, err = Copy(dst, LimitReader(src, n))
|
|
436
|
+
if written == n {
|
|
437
|
+
return n, nil
|
|
438
|
+
}
|
|
439
|
+
if written < n && err == nil {
|
|
440
|
+
// src stopped early; must have been EOF.
|
|
441
|
+
err = EOF
|
|
442
|
+
}
|
|
443
|
+
return
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// CopyBuffer is identical to Copy except that it stages through the provided buffer.
|
|
447
|
+
func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
|
|
448
|
+
if buf != nil && len(buf) == 0 {
|
|
449
|
+
panic("empty buffer in CopyBuffer")
|
|
450
|
+
}
|
|
451
|
+
return copyBuffer(dst, src, buf)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
|
|
455
|
+
if wt, ok := src.(WriterTo); ok {
|
|
456
|
+
return wt.WriteTo(dst)
|
|
457
|
+
}
|
|
458
|
+
if rf, ok := dst.(ReaderFrom); ok {
|
|
459
|
+
return rf.ReadFrom(src)
|
|
460
|
+
}
|
|
461
|
+
if buf == nil {
|
|
462
|
+
size := 32 * 1024
|
|
463
|
+
if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {
|
|
464
|
+
if l.N < 1 {
|
|
465
|
+
size = 1
|
|
466
|
+
} else {
|
|
467
|
+
size = int(l.N)
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
buf = make([]byte, size)
|
|
471
|
+
}
|
|
472
|
+
for {
|
|
473
|
+
nr, er := src.Read(buf)
|
|
474
|
+
if nr > 0 {
|
|
475
|
+
nw, ew := dst.Write(buf[0:nr])
|
|
476
|
+
if nw < 0 || nr < nw {
|
|
477
|
+
nw = 0
|
|
478
|
+
if ew == nil {
|
|
479
|
+
ew = errInvalidWrite
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
written += int64(nw)
|
|
483
|
+
if ew != nil {
|
|
484
|
+
err = ew
|
|
485
|
+
break
|
|
486
|
+
}
|
|
487
|
+
if nr != nw {
|
|
488
|
+
err = ErrShortWrite
|
|
489
|
+
break
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if er != nil {
|
|
493
|
+
if er != EOF {
|
|
494
|
+
err = er
|
|
495
|
+
}
|
|
496
|
+
break
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return written, err
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
var errInvalidWrite = errors.New("invalid write result")
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
//go:build gofront
|
|
2
|
+
|
|
3
|
+
//gofront:target both
|
|
4
|
+
|
|
5
|
+
// Copyright 2021 The Go Authors. All rights reserved.
|
|
6
|
+
// Use of this source code is governed by a BSD-style
|
|
7
|
+
// license that can be found in the LICENSE file.
|
|
8
|
+
|
|
9
|
+
// Package maps defines various functions useful with maps of any type.
|
|
10
|
+
//
|
|
11
|
+
// This package does not have any special handling for non-reflexive keys
|
|
12
|
+
// (keys k where k != k), such as floating-point NaNs.
|
|
13
|
+
package maps
|
|
14
|
+
|
|
15
|
+
import "iter"
|
|
16
|
+
|
|
17
|
+
// Equal reports whether two maps contain the same key/value pairs.
|
|
18
|
+
// Values are compared using ==.
|
|
19
|
+
func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
|
|
20
|
+
if len(m1) != len(m2) {
|
|
21
|
+
return false
|
|
22
|
+
}
|
|
23
|
+
for k, v1 := range m1 {
|
|
24
|
+
if v2, ok := m2[k]; !ok || v1 != v2 {
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return true
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// EqualFunc is like Equal, but compares values using eq.
|
|
32
|
+
// Keys are still compared with ==.
|
|
33
|
+
func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool {
|
|
34
|
+
if len(m1) != len(m2) {
|
|
35
|
+
return false
|
|
36
|
+
}
|
|
37
|
+
for k, v1 := range m1 {
|
|
38
|
+
if v2, ok := m2[k]; !ok || !eq(v1, v2) {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return true
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Clone returns a copy of m. This is a shallow clone:
|
|
46
|
+
// the new keys and values are set using ordinary assignment.
|
|
47
|
+
func Clone[M ~map[K]V, K comparable, V any](m M) M {
|
|
48
|
+
// Preserve nil in case it matters.
|
|
49
|
+
if m == nil {
|
|
50
|
+
return nil
|
|
51
|
+
}
|
|
52
|
+
r := make(M, len(m))
|
|
53
|
+
for k, v := range m {
|
|
54
|
+
r[k] = v
|
|
55
|
+
}
|
|
56
|
+
return r
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Copy copies all key/value pairs in src adding them to dst.
|
|
60
|
+
// When a key in src is already present in dst,
|
|
61
|
+
// the value in dst will be overwritten by the value associated
|
|
62
|
+
// with the key in src.
|
|
63
|
+
func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
|
|
64
|
+
for k, v := range src {
|
|
65
|
+
dst[k] = v
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// DeleteFunc deletes any key/value pairs from m for which del returns true.
|
|
70
|
+
func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
|
|
71
|
+
for k, v := range m {
|
|
72
|
+
if del(k, v) {
|
|
73
|
+
delete(m, k)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// All returns an iterator over key-value pairs from m.
|
|
79
|
+
// The iteration order is not specified and is not guaranteed
|
|
80
|
+
// to be the same from one call to the next.
|
|
81
|
+
func All[Map ~map[K]V, K comparable, V any](m Map) iter.Seq2[K, V] {
|
|
82
|
+
return func(yield func(K, V) bool) {
|
|
83
|
+
for k, v := range m {
|
|
84
|
+
if !yield(k, v) {
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Keys returns an iterator over keys in m.
|
|
92
|
+
// The iteration order is not specified and is not guaranteed
|
|
93
|
+
// to be the same from one call to the next.
|
|
94
|
+
func Keys[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[K] {
|
|
95
|
+
return func(yield func(K) bool) {
|
|
96
|
+
for k := range m {
|
|
97
|
+
if !yield(k) {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Values returns an iterator over values in m.
|
|
105
|
+
// The iteration order is not specified and is not guaranteed
|
|
106
|
+
// to be the same from one call to the next.
|
|
107
|
+
func Values[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[V] {
|
|
108
|
+
return func(yield func(V) bool) {
|
|
109
|
+
for _, v := range m {
|
|
110
|
+
if !yield(v) {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Insert adds the key-value pairs from seq to m.
|
|
118
|
+
// If a key in seq already exists in m, its value will be overwritten.
|
|
119
|
+
func Insert[Map ~map[K]V, K comparable, V any](m Map, seq iter.Seq2[K, V]) {
|
|
120
|
+
for k, v := range seq {
|
|
121
|
+
m[k] = v
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Collect collects key-value pairs from seq into a new map
|
|
126
|
+
// and returns it.
|
|
127
|
+
func Collect[K comparable, V any](seq iter.Seq2[K, V]) map[K]V {
|
|
128
|
+
m := make(map[K]V)
|
|
129
|
+
Insert(m, seq)
|
|
130
|
+
return m
|
|
131
|
+
}
|