Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
100 lines (86 sloc) 2.5 KB
package cmp
import (
// A Result of a Comparison.
type Result interface {
Success() bool
// StringResult is an implementation of Result that reports the error message
// string verbatim and does not provide any templating or formatting of the
// message.
type StringResult struct {
success bool
message string
// Success returns true if the comparison was successful.
func (r StringResult) Success() bool {
return r.success
// FailureMessage returns the message used to provide additional information
// about the failure.
func (r StringResult) FailureMessage() string {
return r.message
// ResultSuccess is a constant which is returned by a ComparisonWithResult to
// indicate success.
var ResultSuccess = StringResult{success: true}
// ResultFailure returns a failed Result with a failure message.
func ResultFailure(message string) StringResult {
return StringResult{message: message}
// ResultFromError returns ResultSuccess if err is nil. Otherwise ResultFailure
// is returned with the error message as the failure message.
func ResultFromError(err error) Result {
if err == nil {
return ResultSuccess
return ResultFailure(err.Error())
type templatedResult struct {
success bool
template string
data map[string]interface{}
func (r templatedResult) Success() bool {
return r.success
func (r templatedResult) FailureMessage(args []ast.Expr) string {
msg, err := renderMessage(r, args)
if err != nil {
return fmt.Sprintf("failed to render failure message: %s", err)
return msg
// ResultFailureTemplate returns a Result with a template string and data which
// can be used to format a failure message. The template may access data from .Data,
// the comparison args with the callArg function, and the formatNode function may
// be used to format the call args.
func ResultFailureTemplate(template string, data map[string]interface{}) Result {
return templatedResult{template: template, data: data}
func renderMessage(result templatedResult, args []ast.Expr) (string, error) {
tmpl := template.New("failure").Funcs(template.FuncMap{
"formatNode": source.FormatNode,
"callArg": func(index int) ast.Expr {
if index >= len(args) {
return nil
return args[index]
var err error
tmpl, err = tmpl.Parse(result.template)
if err != nil {
return "", err
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, map[string]interface{}{
return buf.String(), err
You can’t perform that action at this time.