111 lines
2.6 KiB
Go
111 lines
2.6 KiB
Go
// json.go provides types & functions for json unmarshalling
|
|
|
|
package types
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
// DateTimeFormat is the format used by the Navitia Api for use with time pkg.
|
|
DateTimeFormat string = "20060102T150405" // YYYYMMDDThhmmss
|
|
// DateFormat is when there is no time info
|
|
DateFormat string = "20060102"
|
|
)
|
|
|
|
// parseDateTime parses a time formatted under iso-date-time as indicated in the Navitia api.
|
|
// This is simply parsing a date formatted under the standard ISO 8601.
|
|
// If the given string is empty (i.e ""), then the zero value of time.Time will be returned
|
|
func parseDateTime(datetime string) (time.Time, error) {
|
|
// If there's no datetime given, just return the zero value
|
|
if datetime == "" || datetime == "not-a-date-time" {
|
|
return time.Time{}, nil
|
|
}
|
|
|
|
// If the datetime doesn't countain a "T", then it does not have time info
|
|
var format string
|
|
if strings.Contains(datetime, "T") {
|
|
format = DateTimeFormat
|
|
} else {
|
|
format = DateFormat
|
|
}
|
|
|
|
// Parse it
|
|
res, err := time.Parse(format, datetime)
|
|
if err != nil {
|
|
err = errors.Wrap(err, "parseDateTime: error while parsing datetime")
|
|
}
|
|
return res, err
|
|
}
|
|
|
|
// UnmarshalError is returned when unmarshalling fails
|
|
// It implements both error and github.com/pkg/errors's causer
|
|
type UnmarshalError struct {
|
|
// Type on which the unmarshaller where the error occurred works
|
|
Type string
|
|
|
|
// JSON Key where failure occurred
|
|
Key string
|
|
|
|
// Name of the key in package
|
|
Name string
|
|
|
|
// Value associated with the key
|
|
Value interface{}
|
|
|
|
// Message of the error
|
|
Message string
|
|
|
|
// Underlying error
|
|
Underlying error
|
|
|
|
// Full JSON data
|
|
JSON []byte
|
|
}
|
|
|
|
// Cause implements github.com/pkg/error's causer
|
|
func (err UnmarshalError) Cause() error {
|
|
return err.Underlying
|
|
}
|
|
|
|
// Error implements error
|
|
func (err UnmarshalError) Error() string {
|
|
msg := fmt.Sprintf(
|
|
"(*%s).UnmarshalJSON: Unmarshalling %s (json: \"%s\") with value \"%v\" failed",
|
|
err.Type,
|
|
err.Name,
|
|
err.Key,
|
|
err.Value)
|
|
|
|
if err.Message != "" {
|
|
msg += ": " + err.Message
|
|
}
|
|
if err.Underlying != nil {
|
|
msg += " [" + err.Cause().Error() + "]"
|
|
}
|
|
return msg
|
|
}
|
|
|
|
// unmarshalErrorer allows us to make better error messages
|
|
type unmarshalErrorMaker struct {
|
|
Type string
|
|
JSON []byte
|
|
}
|
|
|
|
// err creates a new UnmarshalError
|
|
func (gen unmarshalErrorMaker) err(underlyingErr error, name string, key string, value interface{}, message string) error {
|
|
return UnmarshalError{
|
|
Type: gen.Type,
|
|
Key: key,
|
|
Name: name,
|
|
Value: value,
|
|
Message: message,
|
|
Underlying: underlyingErr,
|
|
JSON: gen.JSON,
|
|
}
|
|
}
|