Skip to content

Commit c015457

Browse files
committed
page-writer-no-buffer
1 parent 093e9ae commit c015457

File tree

3 files changed

+57
-14
lines changed

3 files changed

+57
-14
lines changed

html_default_page.go

+51-11
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,65 @@ import (
44
"bytes"
55
_ "embed"
66
"io"
7-
"strings"
87
)
98

109
//go:embed html_default_page.html
11-
var DefaultHTMLPageTemplate string
10+
var defaultPageTemplate []byte
1211

13-
func MarshalHTML(v any) []byte {
12+
var DefaultPageMarshaler = PageMarshaler{
13+
Title: "htmljson",
14+
Template: defaultPageTemplate,
15+
TemplateTitleKey: `{{.Title}}`,
16+
TemplateJSONKey: `{{.HTMLJSON}}`,
17+
Marshaler: &DefaultMarshaler,
18+
}
19+
20+
// PageMarshaler encodes JSON via marshaller into HTML page by placing Title and content appropriately.
21+
type PageMarshaler struct {
22+
Title string
23+
Template []byte
24+
TemplateTitleKey string
25+
TemplateJSONKey string
26+
27+
Marshaler interface {
28+
MarshalTo(w io.Writer, v any) error
29+
}
30+
31+
idxTitle int
32+
idxHTMLJSON int
33+
}
34+
35+
func (m *PageMarshaler) Marshal(v any) []byte {
1436
b := bytes.Buffer{}
15-
MarshalHTMLTo(&b, v)
37+
m.MarshalTo(&b, v)
1638
return b.Bytes()
1739
}
1840

19-
func MarshalHTMLTo(w io.Writer, v any) (written int64, err error) {
20-
var b bytes.Buffer
21-
b.Grow(1000)
41+
func (m *PageMarshaler) parseTemplate() {
42+
if m.idxTitle == 0 || m.idxHTMLJSON == 0 {
43+
m.idxTitle = bytes.Index(m.Template, []byte(m.TemplateTitleKey))
44+
m.idxHTMLJSON = bytes.Index(m.Template, []byte(m.TemplateJSONKey))
45+
}
46+
}
47+
48+
func (m *PageMarshaler) MarshalTo(w io.Writer, v any) error {
49+
m.parseTemplate()
50+
51+
var s int
52+
53+
if f := m.idxTitle; f > 0 {
54+
w.Write(m.Template[s:f])
55+
s = f + len(m.TemplateTitleKey)
56+
w.Write([]byte(m.Title))
57+
}
58+
59+
if f := m.idxHTMLJSON; f > 0 {
60+
w.Write(m.Template[s:f])
61+
s = f + len(m.TemplateJSONKey)
62+
m.Marshaler.MarshalTo(w, v)
63+
}
2264

23-
jsonHTML := DefaultMarshaler.Marshal(v)
24-
b.WriteString(strings.ReplaceAll(DefaultHTMLPageTemplate, `{{.HTMLJSON}}`, string(jsonHTML)))
65+
w.Write(m.Template[s:])
2566

26-
n, err := w.Write(b.Bytes())
27-
return int64(n), err
67+
return nil
2868
}

html_default_page.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4-
<title>htmljson</title>
4+
<title>{{.Title}}</title>
55
<style>
66

77
/* Colors from Apple https://developer.apple.com/design/human-interface-guidelines/foundations/color

html_default_page_test.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func TestMarshalHTML(t *testing.T) {
2020
var v any
2121
json.Unmarshal(exampleJSON, &v)
2222

23-
h := htmljson.MarshalHTML(v)
23+
h := htmljson.DefaultPageMarshaler.Marshal(v)
2424

2525
os.WriteFile("testdata/example-page.out.html", h, 0666)
2626
if strings.TrimSpace(examplePageHTML) != strings.TrimSpace(string(h)) {
@@ -50,7 +50,10 @@ func TestMarshalHTML_Color(t *testing.T) {
5050
Row: htmljson.DefaultRowHTML{Padding: 4}.Marshal,
5151
}
5252

53-
htmlPage := strings.ReplaceAll(htmljson.DefaultHTMLPageTemplate, `{{.HTMLJSON}}`, string(s.Marshal(v)))
53+
m := htmljson.DefaultPageMarshaler
54+
m.Marshaler = &s
55+
56+
htmlPage := m.Marshal(v)
5457

5558
os.WriteFile("testdata/example-page-color.out.html", []byte(htmlPage), 0666)
5659
if strings.TrimSpace(examplePageColorHTML) != strings.TrimSpace(string(htmlPage)) {

0 commit comments

Comments
 (0)