gofront 1.7.0 → 1.9.0

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.
Files changed (194) hide show
  1. package/README.md +14 -14
  2. package/package.json +10 -38
  3. package/src/backend/js/expressions.js +2060 -389
  4. package/src/backend/js/index.js +586 -174
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +936 -1644
  7. package/src/backend/js/statements.js +1349 -132
  8. package/src/backend/js/stdlib/index.js +51 -94
  9. package/src/backend/js/templ.js +67 -118
  10. package/src/backend/js/type-info.js +436 -0
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +80 -0
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +753 -872
  15. package/src/backend/wasm/emit-builtins.js +914 -237
  16. package/src/backend/wasm/emit-exprs.js +1456 -195
  17. package/src/backend/wasm/emit-maps.js +78 -380
  18. package/src/backend/wasm/emit-stmts.js +1659 -214
  19. package/src/backend/wasm/emit.js +614 -88
  20. package/src/backend/wasm/encode.js +43 -13
  21. package/src/backend/wasm/globals.js +491 -0
  22. package/src/backend/wasm/glue.js +2 -4
  23. package/src/backend/wasm/index.js +406 -3195
  24. package/src/backend/wasm/method-expr.js +392 -0
  25. package/src/backend/wasm/module-emitter.js +1615 -0
  26. package/src/backend/wasm/monomorph.js +164 -9
  27. package/src/backend/wasm/natives.js +596 -0
  28. package/src/backend/wasm/prescan.js +249 -0
  29. package/src/backend/wasm/prune-funcs.js +89 -0
  30. package/src/backend/wasm/stdlib/index.js +2 -37
  31. package/src/backend/wasm/stdlib/simd.js +293 -28
  32. package/src/backend/wasm/types.js +260 -27
  33. package/src/backend/wasm/variadic.js +93 -0
  34. package/src/backend/wasm/wat.js +47 -20
  35. package/src/{cli-core.js → cli/cli-core.js} +241 -11
  36. package/src/{test-runner.js → cli/test-runner.js} +188 -122
  37. package/src/{vendor.js → cli/vendor.js} +3 -4
  38. package/src/compiler.js +202 -386
  39. package/src/index.js +15 -169
  40. package/src/{lexer.js → lexer/lexer.js} +203 -62
  41. package/src/{templ-lexer.js → lexer/templ-lexer.js} +61 -18
  42. package/src/{tokens.js → lexer/tokens.js} +2 -0
  43. package/src/link/sourcemap.js +97 -0
  44. package/src/link/stdlib.js +737 -0
  45. package/src/link/type-names.js +148 -0
  46. package/src/link/wasm.js +318 -0
  47. package/src/lower/bounds.js +547 -0
  48. package/src/lower/boxing.js +1 -1
  49. package/src/lower/captures.js +267 -64
  50. package/src/lower/embedding.js +32 -3
  51. package/src/lower/errors-as.js +196 -0
  52. package/src/lower/fmt-formatters.js +905 -0
  53. package/src/lower/functions.js +2 -0
  54. package/src/lower/gen-types.js +274 -0
  55. package/src/lower/index.js +33 -19
  56. package/src/lower/json-codecs.js +1379 -0
  57. package/src/lower/ownership.js +47 -8
  58. package/src/lower/range.js +86 -1
  59. package/src/lower/reachability.js +150 -0
  60. package/src/lower/walk.js +12 -0
  61. package/src/parser/declarations.js +83 -15
  62. package/src/parser/expressions.js +110 -18
  63. package/src/parser/index.js +2 -1
  64. package/src/parser/statements.js +38 -22
  65. package/src/{templ-parser.js → parser/templ.js} +179 -17
  66. package/src/parser/types.js +70 -9
  67. package/src/resolver.js +21 -1
  68. package/src/typechecker/assignability.js +291 -19
  69. package/src/typechecker/const-fold.js +399 -0
  70. package/src/typechecker/constants.js +282 -0
  71. package/src/typechecker/expressions.js +1220 -183
  72. package/src/typechecker/index.js +659 -92
  73. package/src/typechecker/init-order.js +426 -0
  74. package/src/typechecker/operand-text.js +40 -0
  75. package/src/typechecker/resolve.js +613 -62
  76. package/src/typechecker/statements.js +212 -20
  77. package/src/typechecker/stdlib/excluded.js +902 -0
  78. package/src/typechecker/stdlib/index.js +38 -0
  79. package/src/typechecker/stdlib/simd.js +65 -15
  80. package/src/typechecker/termination.js +11 -2
  81. package/src/typechecker/types.js +268 -514
  82. package/stdlib/bytes/buffer.go +479 -0
  83. package/stdlib/bytes/bytes.go +1010 -0
  84. package/stdlib/bytes/reader.go +161 -0
  85. package/stdlib/cmp/cmp.go +65 -0
  86. package/stdlib/context/context.go +115 -0
  87. package/stdlib/crypto/rand/rand.go +34 -0
  88. package/stdlib/crypto/sha256/sha256.go +249 -0
  89. package/stdlib/encoding/base64/base64.go +331 -0
  90. package/stdlib/encoding/binary/binary.go +332 -0
  91. package/stdlib/encoding/hex/hex.go +140 -0
  92. package/stdlib/encoding/json/errors.go +31 -0
  93. package/stdlib/encoding/json/indent.go +71 -0
  94. package/stdlib/encoding/json/json.go +62 -0
  95. package/stdlib/encoding/json/number.go +12 -0
  96. package/stdlib/encoding/json/stream.go +173 -0
  97. package/stdlib/errors/errors.go +174 -0
  98. package/stdlib/fmt/errors.go +110 -0
  99. package/stdlib/fmt/format.go +732 -0
  100. package/stdlib/fmt/print.go +1232 -0
  101. package/stdlib/gom/gom.go +293 -0
  102. package/stdlib/hash/hash.go +53 -0
  103. package/stdlib/html/html.go +251 -0
  104. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  105. package/stdlib/internal/jsonrt/dec.go +871 -0
  106. package/stdlib/internal/jsonrt/enc.go +516 -0
  107. package/stdlib/internal/jsonrt/indent.go +135 -0
  108. package/stdlib/internal/jsonrt/number.go +27 -0
  109. package/stdlib/internal/jsonrt/reader.go +73 -0
  110. package/stdlib/internal/jsonrt/scanner.go +658 -0
  111. package/stdlib/io/io.go +502 -0
  112. package/stdlib/iter/iter.go +18 -0
  113. package/stdlib/maps/maps.go +131 -0
  114. package/stdlib/math/bits/bits.go +507 -0
  115. package/stdlib/math/extra.go +272 -0
  116. package/stdlib/math/math.go +439 -0
  117. package/stdlib/math/rand/rand.go +297 -0
  118. package/stdlib/os/os.go +93 -0
  119. package/stdlib/path/filepath/filepath.go +47 -0
  120. package/stdlib/path/path.go +394 -0
  121. package/stdlib/regexp/regexp.go +231 -0
  122. package/stdlib/slices/slices.go +526 -0
  123. package/stdlib/slices/sort.go +209 -0
  124. package/stdlib/slices/zsort_cmp.go +480 -0
  125. package/stdlib/slices/zsort_ordered.go +482 -0
  126. package/stdlib/sort/sort.go +500 -0
  127. package/stdlib/sort/zsort_func.go +480 -0
  128. package/stdlib/sort/zsort_iface.go +480 -0
  129. package/stdlib/strconv/float.go +1699 -0
  130. package/stdlib/strconv/isprint.go +752 -0
  131. package/stdlib/strconv/quote.go +526 -0
  132. package/stdlib/strconv/strconv.go +616 -0
  133. package/stdlib/strings/builder.go +95 -0
  134. package/stdlib/strings/reader.go +163 -0
  135. package/stdlib/strings/replacer.go +102 -0
  136. package/stdlib/strings/strings.go +807 -0
  137. package/stdlib/sync/sync.go +268 -0
  138. package/stdlib/testing/async_js.go +61 -0
  139. package/stdlib/testing/benchmark.go +297 -0
  140. package/stdlib/testing/testing.go +523 -0
  141. package/stdlib/time/duration.go +233 -0
  142. package/stdlib/time/format.go +745 -0
  143. package/stdlib/time/parse.go +790 -0
  144. package/stdlib/time/sleep_js.go +63 -0
  145. package/stdlib/time/time.go +834 -0
  146. package/stdlib/unicode/unicode.go +250 -0
  147. package/stdlib/unicode/utf8/utf8.go +464 -0
  148. package/src/backend/js/stdlib/base64.js +0 -12
  149. package/src/backend/js/stdlib/binary.js +0 -102
  150. package/src/backend/js/stdlib/bits.js +0 -46
  151. package/src/backend/js/stdlib/builder.js +0 -63
  152. package/src/backend/js/stdlib/bytes.js +0 -122
  153. package/src/backend/js/stdlib/errors.js +0 -44
  154. package/src/backend/js/stdlib/fmt.js +0 -178
  155. package/src/backend/js/stdlib/gom.js +0 -155
  156. package/src/backend/js/stdlib/hex.js +0 -17
  157. package/src/backend/js/stdlib/html.js +0 -20
  158. package/src/backend/js/stdlib/io.js +0 -137
  159. package/src/backend/js/stdlib/json.js +0 -972
  160. package/src/backend/js/stdlib/maps.js +0 -45
  161. package/src/backend/js/stdlib/math.js +0 -69
  162. package/src/backend/js/stdlib/os.js +0 -13
  163. package/src/backend/js/stdlib/path.js +0 -48
  164. package/src/backend/js/stdlib/rand.js +0 -32
  165. package/src/backend/js/stdlib/regexp.js +0 -54
  166. package/src/backend/js/stdlib/sha256.js +0 -12
  167. package/src/backend/js/stdlib/shared.js +0 -17
  168. package/src/backend/js/stdlib/simd.js +0 -24
  169. package/src/backend/js/stdlib/slices.js +0 -77
  170. package/src/backend/js/stdlib/sort.js +0 -30
  171. package/src/backend/js/stdlib/strconv.js +0 -74
  172. package/src/backend/js/stdlib/strings.js +0 -222
  173. package/src/backend/js/stdlib/sync.js +0 -13
  174. package/src/backend/js/stdlib/testing.js +0 -34
  175. package/src/backend/js/stdlib/time.js +0 -128
  176. package/src/backend/js/stdlib/unicode.js +0 -25
  177. package/src/backend/js/stdlib/utf8.js +0 -26
  178. package/src/backend/wasm/const-fold.js +0 -205
  179. package/src/backend/wasm/emit-stdlib.js +0 -13
  180. package/src/backend/wasm/stdlib/bytes.js +0 -5039
  181. package/src/backend/wasm/stdlib/core.js +0 -8903
  182. package/src/backend/wasm/stdlib/io.js +0 -2161
  183. package/src/backend/wasm/stdlib/packages.js +0 -2400
  184. package/src/backend/wasm/stdlib/pure.js +0 -720
  185. package/src/backend/wasm/stdlib/time.js +0 -1200
  186. package/src/typechecker/stdlib/core.js +0 -801
  187. package/src/typechecker/stdlib/extended.js +0 -914
  188. package/src/typechecker/stdlib.js +0 -22
  189. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  190. /package/src/{colors.js → cli/colors.js} +0 -0
  191. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  192. /package/src/{minifier.js → cli/minifier.js} +0 -0
  193. /package/src/{project-config.js → cli/project-config.js} +0 -0
  194. /package/src/{pwa.js → cli/pwa.js} +0 -0
@@ -0,0 +1,502 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
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.
7
+ package io
8
+
9
+ import (
10
+ "errors"
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
+
37
+ // Seek whence values.
38
+ const (
39
+ SeekStart = 0 // seek relative to the origin of the file
40
+ SeekCurrent = 1 // seek relative to the current offset
41
+ SeekEnd = 2 // seek relative to the end
42
+ )
43
+
44
+ // ErrShortWrite means that a write accepted fewer bytes than requested
45
+ // but failed to return an explicit error.
46
+ var ErrShortWrite = errors.New("short write")
47
+
48
+ // ErrShortBuffer means that a read required a longer buffer than was provided.
49
+ var ErrShortBuffer = errors.New("short buffer")
50
+
51
+ // ErrUnexpectedEOF means that EOF was encountered in the
52
+ // middle of reading a fixed-size block or data structure.
53
+ var ErrUnexpectedEOF = errors.New("unexpected EOF")
54
+
55
+ // ErrNoProgress is returned by some clients of a Reader when
56
+ // many calls to Read have failed to return any data or error.
57
+ var ErrNoProgress = errors.New("multiple Read calls return no data or error")
58
+
59
+ // ReadCloser is the interface that groups the basic Read and Close methods.
60
+ type ReadCloser interface {
61
+ Reader
62
+ Closer
63
+ }
64
+
65
+ // WriteCloser is the interface that groups the basic Write and Close methods.
66
+ type WriteCloser interface {
67
+ Writer
68
+ Closer
69
+ }
70
+
71
+ // ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
72
+ type ReadWriteCloser interface {
73
+ Reader
74
+ Writer
75
+ Closer
76
+ }
77
+
78
+ // ReadSeeker is the interface that groups the basic Read and Seek methods.
79
+ type ReadSeeker interface {
80
+ Reader
81
+ Seeker
82
+ }
83
+
84
+ // ReadSeekCloser is the interface that groups the basic Read, Seek and Close methods.
85
+ type ReadSeekCloser interface {
86
+ Reader
87
+ Seeker
88
+ Closer
89
+ }
90
+
91
+ // WriteSeeker is the interface that groups the basic Write and Seek methods.
92
+ type WriteSeeker interface {
93
+ Writer
94
+ Seeker
95
+ }
96
+
97
+ // ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
98
+ type ReadWriteSeeker interface {
99
+ Reader
100
+ Writer
101
+ Seeker
102
+ }
103
+
104
+ // Seeker is the interface that wraps the basic Seek method.
105
+ type Seeker interface {
106
+ Seek(offset int64, whence int) (int64, error)
107
+ }
108
+
109
+ // ReaderAt is the interface that wraps the basic ReadAt method.
110
+ type ReaderAt interface {
111
+ ReadAt(p []byte, off int64) (n int, err error)
112
+ }
113
+
114
+ // WriterAt is the interface that wraps the basic WriteAt method.
115
+ type WriterAt interface {
116
+ WriteAt(p []byte, off int64) (n int, err error)
117
+ }
118
+
119
+ // ByteReader is the interface that wraps the ReadByte method.
120
+ type ByteReader interface {
121
+ ReadByte() (byte, error)
122
+ }
123
+
124
+ // ByteScanner is the interface that adds the UnreadByte method to ByteReader.
125
+ type ByteScanner interface {
126
+ ByteReader
127
+ UnreadByte() error
128
+ }
129
+
130
+ // ByteWriter is the interface that wraps the WriteByte method.
131
+ type ByteWriter interface {
132
+ WriteByte(c byte) error
133
+ }
134
+
135
+ // RuneReader is the interface that wraps the ReadRune method.
136
+ type RuneReader interface {
137
+ ReadRune() (r rune, size int, err error)
138
+ }
139
+
140
+ // RuneScanner is the interface that adds the UnreadRune method to RuneReader.
141
+ type RuneScanner interface {
142
+ RuneReader
143
+ UnreadRune() error
144
+ }
145
+
146
+ // StringWriter is the interface that wraps the WriteString method.
147
+ type StringWriter interface {
148
+ WriteString(s string) (n int, err error)
149
+ }
150
+
151
+ // ReaderFrom is the interface that wraps the ReadFrom method.
152
+ type ReaderFrom interface {
153
+ ReadFrom(r Reader) (n int64, err error)
154
+ }
155
+
156
+ // WriterTo is the interface that wraps the WriteTo method.
157
+ type WriterTo interface {
158
+ WriteTo(w Writer) (n int64, err error)
159
+ }
160
+
161
+ // ReadAtLeast reads from r into buf until it has read at least min bytes.
162
+ func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
163
+ if len(buf) < min {
164
+ return 0, ErrShortBuffer
165
+ }
166
+ for n < min && err == nil {
167
+ var nn int
168
+ nn, err = r.Read(buf[n:])
169
+ n += nn
170
+ }
171
+ if n >= min {
172
+ err = nil
173
+ } else if n > 0 && err == EOF {
174
+ err = ErrUnexpectedEOF
175
+ }
176
+ return
177
+ }
178
+
179
+ // ReadFull reads exactly len(buf) bytes from r into buf.
180
+ func ReadFull(r Reader, buf []byte) (n int, err error) {
181
+ n, err = ReadAtLeast(r, buf, len(buf))
182
+ return
183
+ }
184
+
185
+ type nopCloser struct {
186
+ r Reader
187
+ }
188
+
189
+ func (n nopCloser) Read(p []byte) (int, error) {
190
+ rn, err := n.r.Read(p)
191
+ return rn, err
192
+ }
193
+
194
+ func (nopCloser) Close() error {
195
+ return nil
196
+ }
197
+
198
+ // NopCloser returns a ReadCloser with a no-op Close method wrapping r.
199
+ func NopCloser(r Reader) ReadCloser {
200
+ return nopCloser{r: r}
201
+ }
202
+
203
+ type teeReader struct {
204
+ r Reader
205
+ w Writer
206
+ }
207
+
208
+ func (t *teeReader) Read(p []byte) (n int, err error) {
209
+ n, err = t.r.Read(p)
210
+ if n > 0 {
211
+ if _, werr := t.w.Write(p[:n]); werr != nil {
212
+ return n, werr
213
+ }
214
+ }
215
+ return
216
+ }
217
+
218
+ // TeeReader returns a Reader that writes to w what it reads from r.
219
+ func TeeReader(r Reader, w Writer) Reader {
220
+ return &teeReader{r: r, w: w}
221
+ }
222
+
223
+ type multiReader struct {
224
+ readers []Reader
225
+ }
226
+
227
+ func (mr *multiReader) Read(p []byte) (n int, err error) {
228
+ for len(mr.readers) > 0 {
229
+ n, err = mr.readers[0].Read(p)
230
+ if err == EOF {
231
+ mr.readers = mr.readers[1:]
232
+ }
233
+ if n > 0 || err != EOF {
234
+ if err == EOF && len(mr.readers) > 0 {
235
+ err = nil
236
+ }
237
+ return
238
+ }
239
+ }
240
+ return 0, EOF
241
+ }
242
+
243
+ // MultiReader returns a Reader that's the logical concatenation of readers.
244
+ func MultiReader(readers ...Reader) Reader {
245
+ r := make([]Reader, len(readers))
246
+ copy(r, readers)
247
+ return &multiReader{readers: r}
248
+ }
249
+
250
+ type multiWriter struct {
251
+ writers []Writer
252
+ }
253
+
254
+ func (t *multiWriter) Write(p []byte) (n int, err error) {
255
+ for _, w := range t.writers {
256
+ n, err = w.Write(p)
257
+ if err != nil {
258
+ return
259
+ }
260
+ if n != len(p) {
261
+ err = ErrShortWrite
262
+ return
263
+ }
264
+ }
265
+ return len(p), nil
266
+ }
267
+
268
+ func (t *multiWriter) WriteString(s string) (n int, err error) {
269
+ p := []byte(s)
270
+ for _, w := range t.writers {
271
+ n, err = w.Write(p)
272
+ if err != nil {
273
+ return
274
+ }
275
+ if n != len(p) {
276
+ err = ErrShortWrite
277
+ return
278
+ }
279
+ }
280
+ return len(p), nil
281
+ }
282
+
283
+ // MultiWriter creates a writer that duplicates its writes to all writers.
284
+ func MultiWriter(writers ...Writer) Writer {
285
+ allWriters := make([]Writer, 0, len(writers))
286
+ for _, w := range writers {
287
+ if mw, ok := w.(*multiWriter); ok {
288
+ allWriters = append(allWriters, mw.writers...)
289
+ } else {
290
+ allWriters = append(allWriters, w)
291
+ }
292
+ }
293
+ return &multiWriter{writers: allWriters}
294
+ }
295
+
296
+ // SectionReader implements Read, Seek, and ReadAt on a section of an underlying ReaderAt.
297
+ type SectionReader struct {
298
+ r ReaderAt
299
+ base int64
300
+ off int64
301
+ limit int64
302
+ n int64
303
+ }
304
+
305
+ // NewSectionReader returns a SectionReader that reads from r
306
+ // starting at offset off and stops with EOF after n bytes.
307
+ func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
308
+ var remaining int64 = 1<<63 - 1 - off
309
+ if n <= remaining {
310
+ remaining = n
311
+ }
312
+ return &SectionReader{r: r, base: off, off: off, limit: off + remaining, n: n}
313
+ }
314
+
315
+ func (s *SectionReader) Read(p []byte) (n int, err error) {
316
+ if s.off >= s.limit {
317
+ return 0, EOF
318
+ }
319
+ if max := s.limit - s.off; int64(len(p)) > max {
320
+ p = p[0:max]
321
+ }
322
+ n, err = s.r.ReadAt(p, s.off)
323
+ s.off += int64(n)
324
+ return
325
+ }
326
+
327
+ var errWhence = errors.New("Seek: invalid whence")
328
+ var errOffset = errors.New("Seek: invalid offset")
329
+
330
+ func (s *SectionReader) Seek(offset int64, whence int) (int64, error) {
331
+ switch whence {
332
+ default:
333
+ return 0, errWhence
334
+ case SeekStart:
335
+ offset += s.base
336
+ case SeekCurrent:
337
+ offset += s.off
338
+ case SeekEnd:
339
+ offset += s.limit
340
+ }
341
+ if offset < s.base {
342
+ return 0, errOffset
343
+ }
344
+ s.off = offset
345
+ return offset - s.base, nil
346
+ }
347
+
348
+ func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) {
349
+ if off < 0 || off >= s.Size() {
350
+ return 0, EOF
351
+ }
352
+ off += s.base
353
+ if max := s.limit - off; int64(len(p)) > max {
354
+ p = p[0:max]
355
+ n, err = s.r.ReadAt(p, off)
356
+ if err == nil {
357
+ err = EOF
358
+ }
359
+ return n, err
360
+ }
361
+ n, err = s.r.ReadAt(p, off)
362
+ return n, err
363
+ }
364
+
365
+ // Size returns the size of the section in bytes.
366
+ func (s *SectionReader) Size() int64 { return s.limit - s.base }
367
+
368
+ // Outer returns the underlying ReaderAt and offsets for the section.
369
+ func (s *SectionReader) Outer() (r ReaderAt, off int64, n int64) {
370
+ return s.r, s.base, s.n
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,18 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
5
+ // Package iter provides basic definitions related to iterators over
6
+ // sequences. Same API as Go's iter package; Pull and Pull2 need coroutines
7
+ // and are not available.
8
+ package iter
9
+
10
+ // Seq is an iterator over sequences of individual values. When called as
11
+ // seq(yield), seq calls yield(v) for each value v in the sequence, stopping
12
+ // early if yield returns false.
13
+ type Seq[V any] func(yield func(V) bool)
14
+
15
+ // Seq2 is an iterator over sequences of pairs of values, most commonly
16
+ // key-value pairs. When called as seq(yield), seq calls yield(k, v) for each
17
+ // pair (k, v) in the sequence, stopping early if yield returns false.
18
+ type Seq2[K, V any] func(yield func(K, V) bool)
@@ -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
+ }