[mirror] Scalable static site server for Git forges (like GitHub Pages)
1package git_pages
2
3import (
4 "errors"
5 "io"
6 "strings"
7)
8
9type BoundedReader struct {
10 inner io.Reader
11 fuel int64
12 err error
13}
14
15func ReadAtMost(reader io.Reader, count int64, err error) io.Reader {
16 return &BoundedReader{reader, count, err}
17}
18
19func (reader *BoundedReader) Read(dest []byte) (count int, err error) {
20 if reader.fuel <= 0 {
21 return 0, reader.err
22 }
23 if int64(len(dest)) > reader.fuel {
24 dest = dest[0:reader.fuel]
25 }
26 count, err = reader.inner.Read(dest)
27 reader.fuel -= int64(count)
28 return
29}
30
31type prettyError interface {
32 error
33 Pretty() string
34}
35
36func prettyErrMsg(err error) string {
37 switch cerr := err.(type) {
38 case prettyError:
39 return cerr.Pretty()
40 default:
41 return cerr.Error()
42 }
43}
44
45type prettyJoinError struct {
46 errs []error
47}
48
49func joinErrors(errs ...error) error {
50 if err := errors.Join(errs...); err != nil {
51 wrapErr := err.(interface{ Unwrap() []error })
52 return &prettyJoinError{errs: wrapErr.Unwrap()}
53 }
54 return nil
55}
56
57func (e *prettyJoinError) Error() string {
58 var s strings.Builder
59 for i, err := range e.errs {
60 if i > 0 {
61 s.WriteString("; ")
62 }
63 s.WriteString(err.Error())
64 }
65 return s.String()
66}
67
68func (e *prettyJoinError) Pretty() string {
69 var s strings.Builder
70 for i, err := range e.errs {
71 if i > 0 {
72 s.WriteString("\n- ")
73 }
74 s.WriteString(strings.ReplaceAll(prettyErrMsg(err), "\n", "\n "))
75 }
76 return s.String()
77}
78
79func (e *prettyJoinError) Unwrap() []error {
80 return e.errs
81}
82
83func getMediaType(mimeType string) (mediaType string) {
84 mediaType, _, _ = strings.Cut(mimeType, ";")
85 mediaType = strings.TrimSpace(strings.ToLower(mediaType))
86 return
87}