Switch completely to the new validation "ErrorType"
authorMikael Berthe <mikael@lilotux.net>
Sun, 16 Oct 2016 11:52:01 +0200
changeset 9 4b3436c03726
parent 8 955d3add9426
child 10 8dc05ff5dbe2
Switch completely to the new validation "ErrorType" Stay backward-compatible with previous error messages.
errors.go
validate.go
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/errors.go	Sun Oct 16 11:52:01 2016 +0200
@@ -0,0 +1,63 @@
+package takuzu
+
+import "fmt"
+
+// This file contains the takuzu validation error type.
+
+const (
+	ErrorNil = iota
+	ErrorDuplicate
+	ErrorTooManyValues
+	ErrorTooManyAdjacentValues
+)
+
+type validationError struct {
+	ErrorType    int
+	LineNumber   *int
+	ColumnNumber *int
+	CellValue    *int
+}
+
+func (e validationError) Error() string {
+	var axis string
+	var n int
+
+	// Currently we don't have validation errors with both
+	// line and column so we can get the axis:
+	if e.LineNumber != nil {
+		axis = "line"
+		n = *e.LineNumber
+	} else if e.ColumnNumber != nil {
+		axis = "column"
+		n = *e.ColumnNumber
+	}
+
+	switch e.ErrorType {
+	case ErrorNil:
+		return ""
+	case ErrorDuplicate:
+		if axis == "" {
+			return "internal validation error"
+		}
+		return fmt.Sprintf("duplicate %ss (%d)", axis, n)
+	case ErrorTooManyValues:
+		if axis == "" || e.CellValue == nil {
+			return "internal validation error"
+		}
+		var numberStr string
+		if *e.CellValue == 0 {
+			numberStr = "zeroes"
+		} else if *e.CellValue == 1 {
+			numberStr = "ones"
+		} else {
+			return "internal validation error"
+		}
+		return fmt.Sprintf("%s %d: too many %s", axis, n, numberStr)
+	case ErrorTooManyAdjacentValues:
+		if axis == "" || e.CellValue == nil {
+			return "internal validation error"
+		}
+		return fmt.Sprintf("%s %d: 3+ same values %d", axis, n, *e.CellValue)
+	}
+	return "internal validation error"
+}
--- a/validate.go	Sun Oct 16 10:08:11 2016 +0200
+++ b/validate.go	Sun Oct 16 11:52:01 2016 +0200
@@ -1,10 +1,6 @@
 package takuzu
 
-import (
-	"fmt"
-
-	"github.com/pkg/errors"
-)
+// This file contains the takuzu validation functions and methods.
 
 // checkRange returns true if the range is completely defined, and an error
 // if it doesn't follow the rules for a takuzu line or column
@@ -31,7 +27,11 @@
 			if c.Value == prevCell.Value {
 				prevCellCount++
 				if prevCellCount > 2 {
-					return full, errors.Errorf("3+ same values %d", c.Value)
+					v := c.Value
+					return full, validationError{
+						ErrorType: ErrorTooManyAdjacentValues,
+						CellValue: &v,
+					}
 				}
 			} else {
 				prevCellCount = 1
@@ -41,10 +41,18 @@
 		prevCell = c
 	}
 	if counters[0] > size/2 {
-		return full, errors.Errorf("too many zeroes")
+		v := 0
+		return full, validationError{
+			ErrorType: ErrorTooManyValues,
+			CellValue: &v,
+		}
 	}
 	if counters[1] > size/2 {
-		return full, errors.Errorf("too many ones")
+		v := 1
+		return full, validationError{
+			ErrorType: ErrorTooManyValues,
+			CellValue: &v,
+		}
 	}
 	return full, nil
 }
@@ -101,12 +109,18 @@
 		d = b.GetLine(i)
 		full, err = checkRange(d)
 		if err != nil {
-			return false, errors.Wrapf(err, "line %d", i)
+			err := err.(validationError)
+			err.LineNumber = &i
+			return false, err
 		}
 		if full {
 			hv := computeVal(d)
 			if lineVals[hv] {
-				return false, fmt.Errorf("duplicate lines (%d)", i)
+				err := validationError{
+					ErrorType:  ErrorDuplicate,
+					LineNumber: &i,
+				}
+				return false, err
 			}
 			lineVals[hv] = true
 		} else {
@@ -117,12 +131,18 @@
 		d = b.GetColumn(i)
 		full, err = checkRange(d)
 		if err != nil {
-			return false, errors.Wrapf(err, "column %d", i)
+			err := err.(validationError)
+			err.ColumnNumber = &i
+			return false, err
 		}
 		if full {
 			hv := computeVal(d)
 			if colVals[hv] {
-				return false, fmt.Errorf("duplicate columns (%d)", i)
+				err := validationError{
+					ErrorType:    ErrorDuplicate,
+					ColumnNumber: &i,
+				}
+				return false, err
 			}
 			colVals[hv] = true
 		} else {