1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This file contains the code to handle template options.
6
7package template
8
9import "strings"
10
11// missingKeyAction defines how to respond to indexing a map with a key that is not present.
12type missingKeyAction int
13
14const (
15	mapInvalid   missingKeyAction = iota // Return an invalid reflect.Value.
16	mapZeroValue                         // Return the zero value for the map element.
17	mapError                             // Error out
18)
19
20type option struct {
21	missingKey missingKeyAction
22}
23
24// Option sets options for the template. Options are described by
25// strings, either a simple string or "key=value". There can be at
26// most one equals sign in an option string. If the option string
27// is unrecognized or otherwise invalid, Option panics.
28//
29// Known options:
30//
31// missingkey: Control the behavior during execution if a map is
32// indexed with a key that is not present in the map.
33//
34//	"missingkey=default" or "missingkey=invalid"
35//		The default behavior: Do nothing and continue execution.
36//		If printed, the result of the index operation is the string
37//		"<no value>".
38//	"missingkey=zero"
39//		The operation returns the zero value for the map type's element.
40//	"missingkey=error"
41//		Execution stops immediately with an error.
42func (t *Template) Option(opt ...string) *Template {
43	t.init()
44	for _, s := range opt {
45		t.setOption(s)
46	}
47	return t
48}
49
50func (t *Template) setOption(opt string) {
51	if opt == "" {
52		panic("empty option string")
53	}
54	// key=value
55	if key, value, ok := strings.Cut(opt, "="); ok {
56		switch key {
57		case "missingkey":
58			switch value {
59			case "invalid", "default":
60				t.option.missingKey = mapInvalid
61				return
62			case "zero":
63				t.option.missingKey = mapZeroValue
64				return
65			case "error":
66				t.option.missingKey = mapError
67				return
68			}
69		}
70	}
71	panic("unrecognized option: " + opt)
72}
73