commit ab45d1b8595dec2fdb98f1370e1ffc4d65a2099e
parent d85964737a3213a281bdaef6e2e9a93fda706429
Author: gearsix <gearsix@tuta.io>
Date: Sat, 18 Feb 2023 19:05:36 +0000
standardised package errors; added .String() to custom types.
Also made minor improvements to error handling and comment doc in a few
places.
Diffstat:
M | data.go | | | 38 | +++++++++++++++++++++----------------- |
M | template.go | | | 39 | +++++++++++++++++++++++++++++---------- |
2 files changed, 50 insertions(+), 27 deletions(-)
diff --git a/data.go b/data.go
@@ -34,12 +34,22 @@ import (
// data files (lower-case)
type DataFormat string
+// String returns the typical file extension used to
+// represent `df`
+func (df DataFormat) String() string {
+ return string(df)
+}
+
const (
JSON DataFormat = "json"
YAML DataFormat = "yaml"
TOML DataFormat = "toml"
)
+var ErrUnsupportedData = func(format string) error {
+ return fmt.Errorf("data format '%s' is not supported", format)
+}
+
// IsDataFile checks if `path` is one of the known *DatFormat*s.
func IsDataFormat(path string) bool {
return ReadDataFormat(path) != ""
@@ -64,7 +74,7 @@ func ReadDataFormat(path string) DataFormat {
}
for _, fmt := range []DataFormat{JSON, YAML, TOML} {
- if string(fmt) == ext {
+ if fmt.String() == ext {
return fmt
}
}
@@ -89,7 +99,7 @@ func LoadData(format DataFormat, in io.Reader, out interface{}) error {
case TOML:
err = toml.Unmarshal(inbuf, out)
default:
- err = fmt.Errorf("'%s' is not a supported data language", format)
+ err = ErrUnsupportedData(format.String())
}
return err
@@ -100,15 +110,12 @@ func LoadData(format DataFormat, in io.Reader, out interface{}) error {
// as a json). The result is written to the value pointed at by `outp`.
func LoadDataFile(path string, outp interface{}) error {
file, err := os.Open(path)
- defer file.Close()
-
- if err == nil {
- if err = LoadData(ReadDataFormat(path), file, outp); err != nil {
- err = fmt.Errorf("failed to load data '%s': %s", path, err.Error())
- }
+ if err != nil {
+ return err
}
+ defer file.Close()
- return err
+ return LoadData(ReadDataFormat(path), file, outp)
}
// WriteData attempts to write `data` as `format` to `outp`.
@@ -123,7 +130,7 @@ func WriteData(format DataFormat, data interface{}, w io.Writer) error {
case TOML:
err = toml.NewEncoder(w).Encode(data)
default:
- err = fmt.Errorf("'%s' is not a supported data language", format)
+ err = ErrUnsupportedData(format.String())
}
return err
@@ -132,15 +139,12 @@ func WriteData(format DataFormat, data interface{}, w io.Writer) error {
// WriteDataFile attempts to write `data` as `format` to the file at `path`.
// If `force` is *true*, then any existing files will be overwritten.
func WriteDataFile(format DataFormat, data interface{}, path string) (f *os.File, err error) {
- f, err = os.Open(path)
+ if f, err = os.Open(path); err != nil {
+ return
+ }
defer f.Close()
- if err == nil {
- if err = WriteData(format, data, f); err != nil {
- err = fmt.Errorf("faild to write data '%s': %s", path, err.Error())
- }
- }
- if err != nil {
+ if err = WriteData(format, data, f); err != nil {
f = nil
}
diff --git a/template.go b/template.go
@@ -19,6 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import (
"bytes"
+ "errors"
"fmt"
hmpl "html/template"
"io"
@@ -36,12 +37,31 @@ import (
// Template files (lower-case)
type TemplateLanguage string
+func (t TemplateLanguage) String() string {
+ return string(t)
+}
+
const (
TMPL TemplateLanguage = "tmpl"
HMPL TemplateLanguage = "hmpl"
MST TemplateLanguage = "mst"
)
+var (
+ ErrUnsupportedTemplate = func(format string) error {
+ return fmt.Errorf("template language '%s' is not supported", format)
+ }
+ ErrUnknownTemplateType = func(templateType string) error {
+ return fmt.Errorf("unable to infer template type '%s'", templateType)
+ }
+ ErrRootPathIsDir = func(path string) error {
+ return fmt.Errorf("rootPath path must be a file, not a directory (%s)", path)
+ }
+ ErrNilTemplate = errors.New("template is nil")
+)
+
+// IsTemplateLanguage will return a bool if the file found at `path`
+// is a known *TemplateLanguage*, based upon it's file extension.
func IsTemplateLanguage(path string) bool {
return ReadTemplateLangauge(path) != ""
}
@@ -65,7 +85,7 @@ func ReadTemplateLangauge(path string) TemplateLanguage {
}
for _, fmt := range []TemplateLanguage{TMPL, HMPL, MST} {
- if string(fmt) == ext {
+ if fmt.String() == ext {
return fmt
}
}
@@ -91,7 +111,7 @@ func (t *Template) Execute(data interface{}) (result bytes.Buffer, err error) {
var params []reflect.Value
tType := reflect.TypeOf(t.T)
if tType == nil {
- err = fmt.Errorf("template.T is nil")
+ err = ErrNilTemplate
return
}
switch tType.String() {
@@ -102,7 +122,7 @@ func (t *Template) Execute(data interface{}) (result bytes.Buffer, err error) {
funcName = "FRender"
params = []reflect.Value{reflect.ValueOf(&result), reflect.ValueOf(data)}
default:
- err = fmt.Errorf("unable to infer template type '%s'", reflect.TypeOf(t.T).String())
+ err = ErrUnknownTemplateType(reflect.TypeOf(t.T).String())
}
if err == nil {
@@ -123,7 +143,7 @@ func LoadTemplateFile(rootPath string, partialPaths ...string) (t Template, err
if stat, err = os.Stat(rootPath); err != nil {
return
} else if stat.IsDir() {
- err = fmt.Errorf("rootPath path must be a file, not a directory: %s", rootPath)
+ err = ErrRootPathIsDir(rootPath)
return
}
@@ -171,12 +191,11 @@ func LoadTemplateString(lang TemplateLanguage, rootName string, root string, par
return LoadTemplate(lang, rootName, strings.NewReader(root), p)
}
-// LoadTemplate loads a Template from `root` of type `lang`, named
-// `name`. `lang` must be an element in `SupportedTemplateLangs`.
+// LoadTemplate loads a Template from `root` of type `lang`, named `name`.
+// `lang` must be an element in `SupportedTemplateLangs`.
// `name` is optional, if empty the template name will be "template".
-// `root` should be a string of template, with syntax matching that of
-// `lang`. `partials` should be a string of template, with syntax
-// matching that of `lang`.
+// `root` should be a string of template, with syntax matching that of `lang`.
+// `partials` should be a string of template, with syntax matching that of `lang`.
func LoadTemplate(lang TemplateLanguage, rootName string, root io.Reader, partials map[string]io.Reader) (t Template, err error) {
t.Name = rootName
@@ -188,7 +207,7 @@ func LoadTemplate(lang TemplateLanguage, rootName string, root io.Reader, partia
case MST:
t.T, err = loadTemplateMst(rootName, root, partials)
default:
- err = fmt.Errorf("'%s' is not a supported template language", lang)
+ err = ErrUnsupportedTemplate(lang.String())
}
return