Documentation ¶
Overview ¶
Adapted from: https://github.com/gwenn/yacr/blob/b33898940948270a0198c7db28d6b7efc18b783e/reader.go
Index ¶
- Constants
- Variables
- type BoundValidator
- type CSVReader
- func (s *CSVReader) ColumnNumber() int
- func (s *CSVReader) EndOfRecord() bool
- func (s *CSVReader) Err() error
- func (s *CSVReader) Line() string
- func (s *CSVReader) LineNumber() int
- func (s *CSVReader) Read() ([]string, error)
- func (s *CSVReader) Scan() bool
- func (s *CSVReader) ScanLine(r []string) error
- func (s *CSVReader) Text() string
- type Context
- type Error
- type Plan
- type Reader
- type Result
- type TableValidator
- type UniversalReader
- type ValidateFunc
- type ValidationError
- type Validator
Constants ¶
const ( DateLayout = "2006-01-02" DatetimeLayout = "2006-01-02 15:04:05" )
Variables ¶
var DateValidator = &Validator{ Name: "Date", Description: "Validates the input value is a valid date.", RequiresValue: true, Validate: func(s string, cxt Context) *ValidationError { if _, err := time.Parse(DateLayout, s); err != nil { if err := DatetimeValidator.Validate(s, cxt); err == nil { return nil } return &ValidationError{ Err: ErrTypeMismatchDate, } } return nil }, }
DateValidator validates the raw value is date.
var DatetimeValidator = &Validator{ Name: "Datetime", Description: "Validates the input value is a valid date time.", RequiresValue: true, Validate: func(s string, cxt Context) *ValidationError { if _, err := time.Parse(DatetimeLayout, s); err != nil { return &ValidationError{ Err: ErrTypeMismatchDateTime, } } return nil }, }
DatetimeValidator validates the raw value is date.
var EncodingValidator = &Validator{ Name: "Encoding", Description: "Validates a string only contains utf-8 characters.", RequiresValue: true, Validate: func(s string, cxt Context) *ValidationError { if !utf8.ValidString(s) { var bad []rune for i, r := range s { if r == utf8.RuneError { bs, size := utf8.DecodeRuneInString(s[i:]) if size == 1 { bad = append(bad, bs) } } } return &ValidationError{ Err: ErrBadEncoding, Context: Context{ "badRunes": bad, }, } } return nil }, }
var ErrBadEncoding = &Error{
Code: 100,
Description: "UTF-8 encoding required",
}
var ErrBadHeader = &Error{
Code: 201,
Description: "Header does not contain the correct set of fields",
}
var ErrBareQuote = &Error{
Code: 203,
Description: `Value contains bare double quotes (")`,
}
var ErrExtraColumns = &Error{
Code: 202,
Description: "Extra columns were detected in line",
}
var ErrLengthExceeded = &Error{
Code: 302,
Description: "Value exceeds the maximum length",
}
var ErrPrecisionExceeded = &Error{
Code: 303,
Description: "Numeric precision exceeded",
}
var ErrRequiredValue = &Error{
Code: 300,
Description: "Value is required",
}
var ErrScaleExceeded = &Error{
Code: 304,
Description: "Numeric scale exceeded",
}
var ErrTypeMismatch = &Error{
Code: 301,
Description: "Value is not the correct type",
}
var ErrTypeMismatchDate = &Error{
Code: 307,
Description: "Value is not a date (YYYY-MM-DD)",
}
var ErrTypeMismatchDateTime = &Error{
Code: 308,
Description: "Value is not a datetime (YYYY-MM-DD HH:MM:SS)",
}
var ErrTypeMismatchInt = &Error{
Code: 305,
Description: "Value is not an integer (int32)",
}
var ErrTypeMismatchNum = &Error{
Code: 306,
Description: "Value is not a number (float32)",
}
var ErrUnquotedColumn = &Error{
Code: 205,
Description: `Non-empty column must be quoted.`,
}
var ErrUnterminatedColumn = &Error{
Code: 204,
Description: `Column is not terminated with a quote.`,
}
var Errors = map[int]*Error{ 100: ErrBadEncoding, 201: ErrBadHeader, 202: ErrExtraColumns, 203: ErrBareQuote, 300: ErrRequiredValue, 301: ErrTypeMismatch, 302: ErrLengthExceeded, 303: ErrPrecisionExceeded, 304: ErrScaleExceeded, 305: ErrTypeMismatchInt, 306: ErrTypeMismatchNum, 307: ErrTypeMismatchDate, 308: ErrTypeMismatchDateTime, }
Map of errors by code.
var EscapedQuotesValidator = &Validator{ Name: "EscapedQoutes", Description: "Validates any quote characters in a string are escaped.", RequiresValue: true, Validate: func(s string, cxt Context) *ValidationError { i := strings.Index(s, `"`) for i != -1 { if i == len(s)-1 || s[i+1] != '"' { return &ValidationError{ Err: ErrBareQuote, } } else { s = s[i+2:] } i = strings.Index(s, `"`) } return nil }, }
var IntegerValidator = &Validator{ Name: "Integer", Description: "Validates the input string is a valid integer.", RequiresValue: true, Validate: func(s string, cxt Context) *ValidationError { if _, err := strconv.ParseInt(s, 10, 32); err != nil { return &ValidationError{ Err: ErrTypeMismatchInt, } } return nil }, }
IntegerValidator validates the raw value is an integer.
var NumberValidator = &Validator{ Name: "Number", Description: "Validates the input string is a valid number (float).", RequiresValue: true, Validate: func(s string, cxt Context) *ValidationError { if _, err := strconv.ParseFloat(s, 32); err != nil { return &ValidationError{ Err: ErrTypeMismatchNum, } } return nil }, }
NumberValidator validates the raw value is a number.
var RequiredValidator = &Validator{ Name: "Required", Description: "Validates the input value is not empty.", Validate: func(s string, cxt Context) *ValidationError { if s == "" { return &ValidationError{ Err: ErrRequiredValue, } } return nil }, }
RequiredValidator validates the the raw value is not empty. This only applies to fields that are marked as required in the spec.
var StringLengthValidator = &Validator{ Name: "String Length", Description: "Validates the input value is not longer than a pre-defined length.", RequiresValue: true, Validate: func(s string, cxt Context) *ValidationError { length := cxt["length"].(int) if len(s) > length { return &ValidationError{ Err: ErrLengthExceeded, Context: Context{ "maxLength": length, }, } } return nil }, }
StringLengthValidator validates the string value does not exceed a pre-defined length.
var ( // Full semantic version for the service. Version = semver.Version{ Major: progMajor, Minor: progMinor, Patch: progPatch, Pre: []semver.PRVersion{{ VersionStr: progReleaseLevel, }}, } )
Functions ¶
This section is empty.
Types ¶
type BoundValidator ¶
BoundValidator binds a validator to a context.
func Bind ¶
func Bind(v *Validator, cxt Context) *BoundValidator
Bind returns a bound validator given a validator and context.
func BindFieldValidators ¶
func BindFieldValidators(f *client.Field) []*BoundValidator
BindFieldValidators returns a set of validators for the field.
func (*BoundValidator) String ¶
func (b *BoundValidator) String() string
func (*BoundValidator) Validate ¶
func (b *BoundValidator) Validate(s string) *ValidationError
type CSVReader ¶
type CSVReader struct { // If true, the scanner will continue scanning if field-level errors are // encountered. The error should be checked after each call to Scan to // handle the error. ContinueOnError bool // contains filtered or unexported fields }
CSVReader provides an interface for reading CSV data (compatible with rfc4180 and extended with the option of having a separator other than ","). Successive calls to the Scan method will step through the 'fields', skipping the separator/newline between the fields. The EndOfRecord method tells when a field is terminated by a line break.
func DefaultCSVReader ¶
DefaultReader creates a "standard" CSV reader.
func NewCSVReader ¶
NewReader returns a new CSV scanner.
func (*CSVReader) ColumnNumber ¶
ColumnNumber returns the column index of the current field.
func (*CSVReader) EndOfRecord ¶
EndOfRecord returns true when the most recent field has been terminated by a newline (not a separator).
func (*CSVReader) LineNumber ¶
LineNumber returns current line number.
type Error ¶
Error defines a specific type of error denoted by the description. A code is defined as a shorthand for the error and to act as a lookup for the error itself. Errors are classified by code:
- 1xx: encoding related issues
- 2xx: parse related issues
- 3xx: value related issues
type Plan ¶
type Plan struct {
FieldValidators map[string][]*BoundValidator
}
Plan is composed of the set of validators used to evaluate the field values.
type Reader ¶
Reader encapsulates a stdin stream.
type Result ¶
type Result struct {
// contains filtered or unexported fields
}
Result maintains the validation results currently consisting of validation errors.
func (*Result) FieldErrors ¶
func (r *Result) FieldErrors(f string) map[*Error][]*ValidationError
FieldErrors returns errors for field grouped by error code.
func (*Result) LineErrors ¶
func (r *Result) LineErrors() map[*Error][]*ValidationError
LineErrors returns the line errors.
func (*Result) LogError ¶
func (r *Result) LogError(verr *ValidationError)
LogError logs an error to the result.
type TableValidator ¶
type TableValidator struct { Fields *client.Fields Header []string Plan *Plan // contains filtered or unexported fields }
func New ¶
func New(reader io.Reader, table *client.Table) *TableValidator
New takes an io.Reader and validates it against a data model table.
func (*TableValidator) Init ¶
func (t *TableValidator) Init() error
Init initializes the validator by checking the header and compiling a set of validators for each field.
func (*TableValidator) Next ¶
func (t *TableValidator) Next() error
Next reads the next row and validates it. Row and field level errors are logged and not returned. Errors that are returned are EOF and unexpected errors.
func (*TableValidator) Result ¶
func (t *TableValidator) Result() *Result
Result returns the result of the validation.
func (*TableValidator) Run ¶
func (t *TableValidator) Run() error
Run executes all of the validators for the input. All parse and validation errors are handled so the only error that should stop the validator is EOF.
type UniversalReader ¶
type UniversalReader struct {
// contains filtered or unexported fields
}
UniversalReader wraps an io.Reader to replace carriage returns with newlines. This is used with the csv.Reader so it can properly delimit lines.
type ValidateFunc ¶
type ValidateFunc func(value string, cxt Context) *ValidationError
type ValidationError ¶
ValidationError is composed of an error with an optional line and and field the error is specific to. Additional context can be supplied in the context field.
func (ValidationError) Error ¶
func (e ValidationError) Error() string