# HG changeset patch # User Mikael Berthe # Date 1476611521 -7200 # Node ID 4b3436c03726c2595b03cdfed341c336538f51fc # Parent 955d3add9426a89e30f52646d9b7ba92f5f469b0 Switch completely to the new validation "ErrorType" Stay backward-compatible with previous error messages. diff -r 955d3add9426 -r 4b3436c03726 errors.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" +} diff -r 955d3add9426 -r 4b3436c03726 validate.go --- 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 {