Add WriteOnSuccess option

This commit is contained in:
Elara 2023-12-28 07:19:58 -08:00
parent 1634724260
commit 745b6c0e5f
3 changed files with 42 additions and 9 deletions

View File

@ -17,6 +17,9 @@ type Namespace struct {
// to make the resulting document look better. Postprocessing is only done once when the // to make the resulting document look better. Postprocessing is only done once when the
// template is parsed, so it will not affect performance. (default: true) // template is parsed, so it will not affect performance. (default: true)
WhitespaceMutations bool WhitespaceMutations bool
// WriteOnSuccess indicates whether the output should only be written if generation fully succeeds.
// This option buffers the output of the template, so it will use more memory. (default: false)
WriteOnSuccess bool
escapeHTML *bool escapeHTML *bool
} }
@ -27,6 +30,7 @@ func New() *Namespace {
vars: map[string]any{}, vars: map[string]any{},
tags: map[string]Tag{}, tags: map[string]Tag{},
WhitespaceMutations: true, WhitespaceMutations: true,
WriteOnSuccess: false,
} }
} }
@ -66,6 +70,14 @@ func (n *Namespace) WithEscapeHTML(b bool) *Namespace {
return n return n
} }
// WithWriteOnSuccess enables or disables only writing if generation fully succeeds.
func (n *Namespace) WithWriteOnSuccess(b bool) *Namespace {
n.mu.Lock()
defer n.mu.Unlock()
n.WriteOnSuccess = true
return n
}
// WithWhitespaceMutations turns whitespace mutations on or off for the namespace // WithWhitespaceMutations turns whitespace mutations on or off for the namespace
func (n *Namespace) WithWhitespaceMutations(b bool) *Namespace { func (n *Namespace) WithWhitespaceMutations(b bool) *Namespace {
n.mu.Lock() n.mu.Lock()

View File

@ -37,6 +37,7 @@ func (n *Namespace) ParseWithName(name string, r io.Reader) (Template, error) {
ast: astVal.([]ast.Node), ast: astVal.([]ast.Node),
tags: map[string]Tag{}, tags: map[string]Tag{},
vars: map[string]any{}, vars: map[string]any{},
WriteOnSuccess: n.WriteOnSuccess,
} }
if n.WhitespaceMutations { if n.WhitespaceMutations {

View File

@ -2,6 +2,7 @@ package salix
import ( import (
"bufio" "bufio"
"bytes"
"errors" "errors"
"fmt" "fmt"
"html" "html"
@ -22,6 +23,9 @@ type Template struct {
ast []ast.Node ast []ast.Node
escapeHTML *bool escapeHTML *bool
// WriteOnSuccess indicates whether the output should only be written if generation fully succeeds.
// This option buffers the output of the template, so it will use more memory. (default: false)
WriteOnSuccess bool
tags map[string]Tag tags map[string]Tag
vars map[string]any vars map[string]any
@ -56,14 +60,30 @@ func (t Template) WithEscapeHTML(b bool) Template {
return t return t
} }
// WithWriteOnSuccess enables or disables only writing if generation fully succeeds.
func (t Template) WithWriteOnSuccess(b bool) Template {
t.WriteOnSuccess = true
return t
}
// Execute executes a parsed template and writes // Execute executes a parsed template and writes
// the result to w. // the result to w.
func (t Template) Execute(w io.Writer) error { func (t Template) Execute(w io.Writer) error {
t.macros = map[string][]ast.Node{} t.macros = map[string][]ast.Node{}
if t.WriteOnSuccess {
buf := &bytes.Buffer{}
err := t.execute(buf, t.ast, nil)
if err != nil {
return err
}
_, err = io.Copy(w, buf)
return err
} else {
bw := bufio.NewWriterSize(w, 16384) bw := bufio.NewWriterSize(w, 16384)
defer bw.Flush() defer bw.Flush()
return t.execute(bw, t.ast, nil) return t.execute(bw, t.ast, nil)
} }
}
func (t *Template) execute(w io.Writer, nodes []ast.Node, local map[string]any) error { func (t *Template) execute(w io.Writer, nodes []ast.Node, local map[string]any) error {
if local == nil { if local == nil {